2016-01-21 48 views
12

我橫跨方法Array.splice的這種奇怪副作用跑,並蒸餾該代碼下降到必要的最低限度,以重新創建去除值。是的,這很大一部分可以在array.filter的一行中完成,但是我對我是否犯了錯誤或是否有其他事情感興趣。方法Array.splice從剩餘的元素

var array = []; 
 

 
for (var i = 0; i < 10; i++) { 
 
    array.push({ 
 
    value: i 
 
    }); 
 
} 
 

 
array.forEach(function(item, index, intArray) { 
 
    if (item.value % 2 == 1) { 
 
    item.odd = true; 
 
    } else { 
 
    item.odd = false; 
 
    } 
 

 
    if (item.odd) { 
 
    console.log("Removing " + item.value); 
 
    intArray.splice(index, 1); 
 
    } 
 

 
}); 
 

 
console.log(array);

運行在奇數元素此JavaScript結果如預期被去除,但它也除去item.odd值卸下intArray物品2,4,6,和8。拼接線帶回奇數數組元素,但它也爲所有元素帶回item.odd值。

我已經在FF和Chrome中測試過了。即使只有項目傳入回調函數,通過array.indexOf計算索引,並從循環外部引用數組,該行爲仍然存在。

+3

我想知道在循環播放時是否會編輯數組。也許'index'值是原始數組中的索引,而不是新修改的索引。 –

+0

我有類似的想法。不過,我認爲這種情況下的錯誤是項目和索引不符合預期,所以太多或太少的元素被刪除,而不是元素中的值消失。 另外,如果這是我會在尋找通過指數步入回調,並計算其在即時之間的差異的情況下 - 但他們的工作出了相同的做法。 –

回答

9

我認爲,當你在拼接每個奇數的陣列中,forEach最終跳過的下一個項目,這是一個偶數。所以這些項目根本不會被修改。

var array = []; 
 

 
for (var i = 0; i < 10; i++) { 
 
    array.push({ 
 
    value: i 
 
    }); 
 
} 
 

 
array.forEach(function(item, index, intArray) { 
 
    console.log(item); // only prints out 0, 1, 3, 5, 7, 9 
 

 
    if (item.value % 2 == 1) { 
 
    item.odd = true; 
 
    } else { 
 
    item.odd = false; 
 
    } 
 

 
    if (item.odd) { 
 
    console.log("Removing " + item.value); 
 
    intArray.splice(index, 1); 
 
    } 
 

 
}); 
 

 
console.log(array);

換句話說,只有forEach一次訪問每個索引。所以說它到達項目1,它在索引1處。它刪除項目1.項目2現在在索引1處。但是索引1已經被訪問,所以它移動到索引2處的項目,該項目現在是項目3.

+1

這可以解釋爲什麼'0'是奇數屬性中唯一的「偶數」項。 –

+0

通過代碼 - 它看起來很適合我。我想我們必須選擇允許在快照上操作的便利性,還是允許對正在操作的數組進行迭代修改。 –