array.splice从剩余元素中删除值

时间:2016-01-21 19:26:00

标签: javascript arrays

我遇到了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计算,并从循环外部引用该数组。

1 个答案:

答案 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。