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

时间:2017-08-20 14:29:15

标签: 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/>";

}
&#13;
<button onclick="test();">Press to test</button>

<br/><br/>
<div id="output"></div>
&#13;
&#13;
&#13;

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

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

2 个答案:

答案 0 :(得分:9)

那是因为在array1的情况下它包含三个数组,但是它们都指向同一个引用变量,在执行new Array(n)时进行了评估:

var array1 = new Array(n).fill(new Array(n));

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

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

&#13;
&#13;
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/>";

}
&#13;
<button onclick="test();">Press to test</button>

<br/><br/>
<div id="output"></div>
&#13;
&#13;
&#13;

答案 1 :(得分: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);
}
<button onclick="test();">Press to test</button><br/><br/>
<div id="output"></div>

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

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

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