为什么这两个javascript 2d阵列的行为有所不同?

Sac*_*cha 6 javascript arrays multidimensional-array

在我的函数中,我定义了两个数组,第一个(array1),具有预初始化的长度.我添加了第二个数组(array2)仅用于测试,因为我认为第一个表现很奇怪.

我的代码:

function test(n = 3) {
  array1 = new Array(n).fill(new Array(n));
  array2 = [
    [undefined, undefined, undefined],
    [undefined, undefined, undefined],
    [undefined, undefined, undefined]
  ];

  document.getElementById("output").innerHTML = JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><hr/>";


  for (i = 0; i < n; i++) {
    array1[i][0] = i;
    array2[i][0] = i;
  }

  document.getElementById("output").innerHTML += JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><hr/>";

}
Run Code Online (Sandbox Code Playgroud)
<button onclick="test();">Press to test</button>

<br/><br/>
<div id="output"></div>
Run Code Online (Sandbox Code Playgroud)

for循环中,我尝试更改第二个维度的第一个值.它应该输出[[0, undefined, undefined], [1, undefined, undefined], [2, undefined, undefined]],就像第二个数组一样.

我的问题是:为什么会这样?而且,如何在两个维度上创建一个长度为n的预初始化数组,其行为类似于第二个数组?

Nis*_*arg 9

那是因为如果array1它包含三个数组,但它们都指向同一个引用变量,那么在new Array(n)执行时会对它进行评估:

var array1 = new Array(n).fill(new Array(n));
Run Code Online (Sandbox Code Playgroud)

因此,当for循环运行时,array1它设置相同数组引用的值,而在array2这三个数组的情况下是不同的引用变量.

这是你的代码片段的略微修改版本.当array1正在更改's元素的值时,请注意进入控制台的条目.如果array1所有三个子数组都在更改,而在array2使用索引的循环下引用的数组i是唯一更改的数组.

function test(n = 3) {
  array1 = new Array(n).fill(new Array(n));
  array2 = [
    [undefined, undefined, undefined],
    [undefined, undefined, undefined],
    [undefined, undefined, undefined]
  ];

  document.getElementById("output").innerHTML = JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><i>The commas with nothing in between mean undefined.</i><hr/>";


  for (i = 0; i < n; i++) {
    array1[i][0] = i;
    array2[i][0] = i;
    console.log("Array 1: " + JSON.stringify(array1));
    console.log("Array 2: " + JSON.stringify(array2));
  }

  document.getElementById("output").innerHTML += JSON.stringify(array1) + " (array 1) <br/>" + JSON.stringify(array2) + " (array 2)<br/><br/><i>The commas with nothing in between mean undefined.</i><hr/>";

}
Run Code Online (Sandbox Code Playgroud)
<button onclick="test();">Press to test</button>

<br/><br/>
<div id="output"></div>
Run Code Online (Sandbox Code Playgroud)


Nin*_*olz 6

因为 Array.fill

fill()方法使用静态值将数组的所有元素从起始索引填充到结束索引.

获取静态值并使用它填充数组.因此,您可以获得array1相同填充数组的每个元素.

function test(n = 3) {
    var array1 = new Array(n).fill(new Array(n)),
        array2 = [[undefined, undefined, undefined], [undefined, undefined, undefined], [undefined, undefined, undefined]],
        i;

    for (i = 0; i < n; i++) {
        array1[i][0] = i;
        array2[i][0] = i;
    }

    document.getElementById("output").innerHTML = array1 + " (array 1) <br/>" + array2 + " (array 2)<br/><br/><i>The commas with nothing in between mean undefined.</i>";
    console.log(array1);
    console.log(array2);
}
Run Code Online (Sandbox Code Playgroud)
<button onclick="test();">Press to test</button><br/><br/>
<div id="output"></div>
Run Code Online (Sandbox Code Playgroud)

要获得独立的填充数组,您可以使用Array.from映射值并映射新数组.

var array = Array.from({ length: 3 }, _ => Array.from({ length: 3 }, _ => 4));

array[0][0] = 0;
console.log(array);
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)