我遇到了array.splice的这种奇怪的副作用,并将代码提炼到最低限度以重新创建。是的,其中大部分都可以在array.filter的一行上完成,但我对是否犯了错误或是否还有其他事情感兴趣。
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会导致奇数元素按预期被删除,但它也删除了项目2,4,6和8的item.odd值。删除intArray.splice行会返回奇数数组元素,但是它还会返回所有元素的item.odd值。
我在FF和Chrome中测试了这个。即使只将项传递给回调,该行为仍然存在,索引通过array.indexOf计算,并从循环外部引用该数组。
答案 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。