为什么要这样做:
let matrix = Array(3).fill(new Array(3).fill(0));
matrix[0][1] = 1
我希望矩阵为:
[ [0,1,0],
[0,0,0],
[0,0,0] ]
但是,矩阵看起来像这样:
[ [0,1,0],
[0,1,0],
[0,1,0] ]
因此,它将设置整个列而不是仅设置单元格。我觉得我在这里错过了非常重要的一门语言。
提前谢谢!
答案 0 :(得分:2)
因为您在内存中为所有索引使用了相同的引用。
想象这是内存,索引指向内存中的相同值,因此,特定索引的每次更改都会修改该值
new Array(3).fill(0) Matrix
+---------+ +-----------+
| [0,0,0] | <--+------| Index 0 |
+---------+ | +-----------+
^ +------| Index 1 |
| +-----------+
+---------------| Index 2 |
+-----------+
为每个索引创建一个新数组
{length: 3}, () => Array(3).fill(0) Matrix
+---------+ +-----------+
| [0,0,0] | <-----------------------| Index 0 |
+---------+ +-----------+
| [0,0,0] | <-----------------------| Index 1 |
+---------+ +-----------+
| [0,0,0] | <-----------------------| Index 2 |
+---------+ +-----------+
let matrix = Array.from({length: 3}, () => Array(3).fill(0));
matrix[0][1] = 1;
console.log(matrix);
答案 1 :(得分:1)
当您使用.fill
并将其传递给非基元对象(例如对象或数组)时,内存中将只有这些实际对象中的一个。数组将使用对同一对象的三个引用填充,因此,当一个索引发生突变时,它们全部都会被引用。如果要用单独的对象填充数组,则必须在创建新数组的每次迭代中显式创建它们,您可以使用Array.from
:
const matrix = Array.from(
{ length: 3 },
() => new Array(3).fill(0)
);
matrix[0][1] = 1;
console.log(matrix);
仅将.fill
与基元一起使用,或者当您非常确定时,您希望在一个数组中对同一对象有多个引用。
答案 2 :(得分:1)
由于“外部”数组索引仅引用一个数组,因此您也可以首先fill
用零来初始化数组,然后使用map
在每个索引处创建新数组:
let matrix = Array(3).fill(0).map(n => new Array(3).fill(0));
matrix[0][1] = 1;
console.log(matrix);