You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript forEach循环中splice与filter删除元素的差异解析

核心原理说明

这两种操作的差异本质上是两个底层机制共同作用的结果:forEach的执行逻辑、splice和filter的数组操作特性。

1. 先明确forEach的运行规则

你调用arr.forEach()的瞬间,forEach就会捕获当前arr指向的原数组引用,同时固定初始遍历逻辑,整个遍历过程只会操作最开始拿到的这个数组对象,不会中途重新读取arr变量的最新指向。

2. splice影响遍历的原因

splice是修改性方法,直接对原数组的内存数据做改动,不会生成新数组:
你示例里的遍历过程是这样的:

  • 初始原数组为[1,2,3,4],forEach要遍历索引0到3
  • 索引0:打印1,无修改
  • 索引1:打印2,触发splice操作,原数组直接被改成[1,3,4],长度从4变成3
  • 索引2:现在原数组索引2位置的元素是4,直接打印4
  • 索引3:原数组当前长度只有3,不存在索引3,遍历结束
    所以最终打印结果是1,2,4。

3. filter不影响遍历的原因

filter是非修改性方法,它完全不会改动原数组,只会返回一个全新的数组对象:
你示例里写的arr = arr.filter(el => el !== 2),只是把arr这个变量的指向从旧数组改成了新生成的[1,3,4],但forEach最开始绑定的旧数组[1,2,3,4]本身没有任何变化,遍历全程还是对着旧数组走:

  • 索引0:打印1
  • 索引1:打印2,修改arr变量指向新数组,旧数组不变
  • 索引2:旧数组索引2是3,打印3
  • 索引3:旧数组索引3是4,打印4
    所以最终打印结果是1,2,3,4。

补充避坑提示

如果需要在遍历中删除数组元素,更稳妥的方式是直接用filter生成符合要求的新数组后再做后续操作,避免直接修改原数组带来的遍历异常。


内容的提问来源于stack exchange,提问作者n8o

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 01:48:02