首页 > 解决方案 > JS - forEach 循环中的过滤器与拼接

问题描述

背景知识

splice我们可以使用and来改变一个数组filterfilter不是可变方法,而是splice可变方法。所以如果我们使用splice一个数组,那么原来的数组就会发生变异。

问题

现在,我们将对forEach一个数组进行处理,如果条件匹配,我们将使用spliceand删除一个元素filter。让我们来看看:

1.splice

let arr = [1, 2, 3, 4];

arr.forEach(el => {
  console.log(el);
  
  if (el === 2) {
    arr.splice(el, 1); // remove element 2
  }
});

是的,这就是我们所期望的。打印出来1, 2, 4。因为在循环的中间我们改变了arr,结果被破坏了。

2.filter

let arr = [1,2,3,4];

arr.forEach(el => {
  console.log(el);

  if (el === 2) {
    arr = arr.filter(el => el !== 2); // remove element 2
  }
});

但是,正如您所看到的,1, 2, 3, 4即使我们arr在循环中间改变了,它也会打印出来!

问题

我们以类似的方式在循环中间对两个数组进行了变异,但结果不同!发生了什么?

为什么会splice影响原始数组但filter不影响?

标签: javascriptarrays

解决方案


这就是Array.prototype.spliceArray.prototype.filterArray.prototype.forEach的定义方式。splice旨在修改数组(并返回已删除的值),而filter旨在返回仅包含匹配值的数组副本

Array.prototype.forEach按索引升序遍历数组。即使您在例如索引 3 期间修改了数组,下一次迭代它也只会转到下一个索引,例如 4,除非已经到达数组的末尾。请注意,一旦.forEach在数组上调用,它将继续在该数组上工作。您设置arr为另一个值不会影响数组或.forEach调用的状态。类似于常规函数调用:

let someVariable = 5;
function test(param) {
    someVariable = 6;
    console.log(param); // still prints 5
}
test(someVariable);

毕竟,JavaScript 通过引用(或原始值)工作,您不会someVariable像在其他一些语言中那样传递指向变量的指针。


推荐阅读