2013-03-06 66 views
0

当用户点击一个按钮时,我抓住availableTags阵列,将它存储在新的var tagsToWorkWith中。然后我遍历每个行上的tagsToWorkWith并运行moveTag(),以便移动availableTags中的每个标记。迭代数组并使用splice()更新父数组?

moveTag()里面,我使用splice()availableTags中删除那一行。但是,由于某种原因,这将从tagsToWorkWith中删除该行,这会导致我的for()函数仅在每隔一行上运行moveTag()

为什么splice()tagsToWorkWith删除行?我明确地设置tagsToWorkWith等于原来的availableTags,以避免这个问题,但似乎并没有工作。

下面的代码与错误的http://jsfiddle.net/EdnxH/

var availableTags = [{"label":"Label A","value":"1"},{"label":"Label B","value":"2"}, {"label":"Label C","value":"3"}]; 

$(document).on('click', '#clickButton', function() { 
    var tagsToWorkWith = availableTags;       
    for(var countera=0; countera< tagsToWorkWith.length; countera++) { 
     alert(tagsToWorkWith[countera].label); 
     moveTag(tagsToWorkWith[countera].label, tagsToWorkWith[countera].value); 
     //This should match the first alert label, since we haven't increased the counter yet. But, for some reason, moveTag()'s splice() removes the row from tagsToWorkWith. 
     alert(tagsToWorkWith[countera].label); 
    } 
}); 

function moveTag(itemToMove, itemToMoveValue) { 
    var selectedTagArrayIndex = -1;  
    for(var counter=0; counter< availableTags.length; counter++) { 
     if (availableTags[counter].value == itemToMoveValue) { 
      selectedTagArrayIndex = counter; 
     } 
    } 
    if (selectedTagArrayIndex > -1) { 
     availableTags.splice(selectedTagArrayIndex, 1); 
    } 
} 

回答

4

数组是对象运行,而对象不是“深复制”当你将变量之间的引用。因此,你的两个变量都引用完全相同的对象。

这样:

var a = ["hello", "world"]; 
var b = a; 
a[2] = "again"; 
alert(b[2]); // "again" because "a" and "b" are the same object 

如果你想使一个数组的副本,你可以使用:

var b = a.slice(0); 
+0

作品完美,感谢你注意到关于深拷贝。由于我已经加载了jQuery库,你知道'a.slice(0)'和'jQuery.extend(true,{},a)'之间是否存在主要的速度差异:http: //sackoverflow.com/a/122704/761793 – 2013-03-06 15:55:22

+0

通过阅读引用问题的更多答案后,我看到'slice(0)'做了更多的软性克隆,与我引用的函数不同。我会继续做更多的阅读并继续前进,谢谢! – 2013-03-06 15:59:06

+0

@John是的,这是一个“浅”副本。如果数组中包含对象,那么这些对象不会被深度复制。 – Pointy 2013-03-06 16:02:03