我有一个数组ele
,我想用ele
的副本填充另一个数组arr
,然后返回填充的数组。 我拥有的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
相同的输出? 也就是说:为什么我不能通过将ele
分配给arr[i]
来填充arr
,而必须通过将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;
}
实际上,Firebug的输出在这种情况下†非常有用。它告诉您生成的数组的每个元素都引用同一个数组:
[#1=[0, 1], #1#, #1#]
// ^----------^----^
#1
(或#1#
(是数组[0, 1]
的占位符,表示引用。
它仍然是一个数组数组,只是Firebug的表示方式不同。
我不确定这是否是你想要的。例如,如果修改第一个数组的第一个元素:
result[0][0] = 5;
结果将是
[[5,1], [5,1], [5,1]]
我假设您希望数组彼此独立,因此每次都必须分配一个新数组。这就是您在第二种情况下所做的。
†:但它也提醒我们,一个人不应该总是相信他所看到的一切。例如,对象的状态可能与工具表示它的方式大不相同。这是一篇关于这种情况的文章(抱歉自我宣传(,该问题在Firebug中已修复,但在Chrome(afaik(中未修复。