我在JavaScript中创建一个3x3网格,所有值都初始化为false
,如下所示:
let myGrid = Array(3).fill(Array(3).fill(false));
初始化后,网格值为:
[false, false, false],
[false, false, false],
[false, false, false]
如果我然后将元素[0,0]设置为true,例如:
myGrid[0][0] = true;
我希望这些值是:
[true, false, false],
[false, false, false],
[false, false, false]
但实际上,生成的2d数组变为:
[true, false, false],
[true, false, false],
[true, false, false]
当我只设置第一个数组的第一个元素时,为什么每个内部数组中的第一个元素都会改变?
答案 0 :(得分:1)
fill()
,当传递一个数组时,填充对该数组的引用。因此,您的第二维数组实际上是相同的数组。无论你对一个人做了什么都做了它的参考,这自然会反映在指向那个参考的所有其他人身上。
为了说明这一点,你在问题中所做的与做同样的事情是:
var $a = [false, false, false];
let myGrid = array(3);
myGrid[0] = $a;
myGrid[1] = $a;
myGrid[2] = $a;
每次更改说myGrid[0]
的值时,您实际上都在访问$a
的引用,因为该引用仍然是myGrid[1]
和myGrid[2]
点到,你实际上也会修改它们。
为避免这种情况,每次要为myGrid
数组赋值时,都必须定义一个新数组。
答案 1 :(得分:0)
那是因为你的网格是一个相同阵列3倍的数组。
如果您看到初始化代码分为两行,可能会更清楚:
let line = Array(3).fill(false); // [false, false, false], alright
let myGrid = Array(3).fill(line); // wrong: you fill the array with 3 times the same object (the array created at line above)
编辑:初始化数组的更正确的方法(不确定它是最好的):
let myGrid = Array(3).fill(0).map(x => [false, false, false])