JavaScript 2D数组填充中的意外输出

时间:2012-02-28 20:27:53

标签: javascript multidimensional-array

我有一个数组ele,我希望用arr的副本填充另一个数组ele,然后返回填充的数组。我的JavaScript函数是:

function foo(n) {
    var arr = new Array(n);
    var ele = [0,1];

    for(var i=0;i<n;i++) {
        arr[i] = ele;
    }
    return arr;
}

例如foo(3),我想要的输出是[[0,1],[0,1],[0,1]],但我得到输出:[#1=[0, 1], #1#, #1#](使用Firefox的Web控制台)。当我用[0,1]直接填充arr时,如

function fooNew(n) {
    var arr = new Array(n);

    for(var i=0;i<n;i++) {
        arr[i] = [0,1];
    }
    return arr;
}

我得到fooNew(3)的正确输出:[[0,1],[0,1],[0,1]]。为什么我的原始函数foo没有提供与fooNew相同的输出?也就是说:为什么我不能通过将arr分配给ele来填充arr[i],而是必须通过将ele的内容直接分配到arr[i]来填充它。 ,获得我想要的输出?

==

更新:根据Felix Kling的有用答案,经过一些谷歌搜索,我发现通过使用slice(0),你可以将ele的副本放入arr [i]而不是引用它。因此foo的以下修改将提供所需的输出:

function foo(n) {
    var arr = new Array(n);
    var ele = [0,1];

    for(var i=0;i<n;i++) {
        arr[i] = ele.slice(0);
    }

    return arr;
}

1 个答案:

答案 0 :(得分:4)

实际上,在这种情况下,Firebug的输出非常有用。它告诉您结果数组的每个元素都引用相同的数组:

  [#1=[0, 1], #1#, #1#]
//  ^----------^----^  

#1(或#1#)是数组[0, 1]的占位符,表示引用。

它仍然是一个数组数组,它​​只是由Firebug表示。

我不确定这是不是你想要的。例如,如果修改第一个数组的第一个元素:

result[0][0] = 5;

结果将是

[[5,1], [5,1], [5,1]]

我假设您希望阵列彼此独立,因此您每次都必须分配一个新阵列。这就是你在第二种情况下所做的。


†:但它也提醒人们不应该总是相信所看到的一切。对象的状态(例如)可能与工具表示的状态完全不同。 Here is an article about such a case(对不起自我推销),问题已在Firebug中修复,但不在Chrome(afaik)中修复。