【问题标题】:Iterating over array and using splice() updates the parent array?遍历数组并使用 splice() 更新父数组?
【发布时间】:2013-03-06 15:44:46
【问题描述】:

当用户单击按钮时,我会抓取availableTags 数组,并将其存储在新的var tagsToWorkWith 中。然后我遍历tagsToWorkWith 并在每一行上运行moveTag(),以便移动availableTags 中的每个标签。

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);
   }
}

【问题讨论】:

    标签: javascript jquery iteration


    【解决方案1】:

    数组是对象,当您在变量之间分配引用时,对象不会“深度复制”。因此,您的两个变量都引用了完全相同的对象。

    因此:

    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);
    

    【讨论】:

    • 完美运行,感谢您提供有关深度复制的说明。由于我已经加载了 jQuery 库,您知道a.slice(0)jQuery.extend(true, {}, a); 之间是否存在主要的速度差异,如下所示:stackoverflow.com/a/122704/761793
    • 在阅读了引用问题的更多答案后,我看到slice(0) 做了更多的软克隆,与我引用的函数不同。我会继续阅读并继续前进,谢谢!
    • @John 是的,这是一个“浅”的副本。如果数组中有对象,则这些对象不会被深度复制。
    猜你喜欢
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 2015-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多