请向我解释一下。我正在尝试使用for循环创建一个数组数组。当它不起作用时,我尝试简化代码以理解Javascript正在做什么,但简单的代码也没有意义。
function test(){
var sub_array = [];
var super_array =[];
for (var i=1;i<=3;i++){
sub_array.push(i);
super_array.push(sub_array);
}
alert(super_array);
}
我希望看到[1; 1,2; 1,2,3]。 取而代之的是[1,2,3; 1,2,3; 1,2,3]。 如果我循环0-2并按索引分配,我会得到相同的现象。
答案 0 :(得分:16)
您总是将对同一数组的引用推送到超级数组中。
要解决该问题,您可以在推送之前使用slice()克隆子阵列:
function test() {
var sub_array = [];
var super_array = [];
for (var i = 1; i <= 3; i++) {
sub_array.push(i);
super_array.push(sub_array.slice(0));
}
alert(super_array);
}
编辑:正如Dan D.在下面正确指出的那样,你也可以不用参数而不是slice(0)
来调用concat()。根据{{3}}(我自己没有测量),它更快:
for (var i = 1; i <= 3; i++) {
sub_array.push(i);
super_array.push(sub_array.concat());
}
答案 1 :(得分:6)
当你按下“sub_array”时,你并没有推送它的副本。您最终在“super_array”中使用相同的数组三次。 (我应该说你将引用推送到同一个数组三次。)
你可以这样做:
// ...
super_array.push(sub_array.slice(0));
制作副本。
答案 2 :(得分:2)
好。你必须要理解,数组,对象,函数等是javascript中的引用(只有Numbers(Int,Floats等)和字符串是“按值”传递的,这意味着,值被复制/复制)!
如果您有var a=[];
,并且说var b=a
并添加b.push("bla")
,那么即使您将其添加到b,也会向您显示“bla”条目。
换一种说法; a和b是javascript,就像妈妈在frige上的一个音符说“左边的三明治是给你的”。然后你知道,从冰箱里取出左边的三明治而不是随机三明治。她也可以在你家的门上写下另一张纸条(变量b),这样你就知道去哪儿,如果你赶时间的话就去寻找三明治。
如果她把三明治贴在门上......好吧,那会很尴尬。 JS也对此有同感:)
所以问题的解决方案就像休耕一样;
function test(){
var super_array =[];
for (var i=1;i<=3;i++){
var subarray=[];
for (var u=1;u<=4-i;u++){
sub_array.push(u);
super_array.push(subarray);
}
}
alert(super_array);
}
通过重新定义子数组,您可以创建新的引用。因此变量b(小时'门上的第二个音符)现在指向不同三明治的方向 - 也许是爸爸的三明治。
我希望我能帮助你理解这一点。
答案 3 :(得分:1)
请注意,对于for循环中的每次迭代,您都将相同的数组推送到super_array中。请尝试以下方法:
function test(){
var sub_array = [];
var super_array =[];
for (var i=1;i<=3;i++){
sub_array = sub_array.slice(0,sub_array.length);
sub_array.push(i);
super_array.push(sub_array);
}
alert(super_array);
}
答案 4 :(得分:0)
与添加到super_array的子数组相同。那么为什么它必须是不同的。
您没有创建新阵列并推入super_array。
答案 5 :(得分:0)
sub_array
被存储为super_array
中的引用,这意味着当您更改sub_array
时,更改会反映在super_array