背景知识
我们可以使用splice
和filter
来变异数组。filter
不是可变方法,但splice
是可变方法。因此,如果我们对一个数组使用splice
,那么原始数组就会发生变异。
问题所在
现在,我们将对数组执行forEach
,如果条件匹配,我们将使用splice
和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
?
发布于 2021-07-29 16:35:14
这就是定义Array.prototype.splice、Array.prototype.filter和Array.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
变量的指针。
https://stackoverflow.com/questions/68579693
复制相似问题