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

为何使用forEach遍历数组时会跳过偶数索引元素?

为什么用forEach遍历数组删除元素时会跳过偶数索引?

这个问题我之前踩过一模一样的坑!核心原因在于forEach的遍历机制和数组动态修改之间的冲突,咱们一步步拆解清楚:

1. forEach的底层遍历逻辑

forEach在执行的瞬间,就会先记录数组的初始长度,然后严格按照索引从0到初始length-1的序列依次遍历。也就是说,它的遍历计划是一开始就定死的,不会因为遍历过程中数组的长度、元素位置变化而动态调整索引。

2. 模拟你的场景(用具体例子看过程)

假设你的数组b初始是[1,2,3,4,5,6],你在forEach里写了类似这样的删除逻辑:

b.forEach((item, index) => {
  // 简化条件:直接删除当前索引的元素
  b.splice(index, 1);
});

咱们一步步走一遍遍历流程:

  • 初始状态:数组长度6,forEach要遍历的索引是0、1、2、3、4、5
  • 索引0:删除元素1,数组变成[2,3,4,5,6](长度缩为5)
  • 索引1:此时数组的索引1对应原本的元素3(因为元素2前移到了索引0),删除它后数组变成[2,4,5,6](长度缩为4)
  • 索引2:数组的索引2对应原本的元素5(元素4前移到了索引1),删除它后数组变成[2,4,6](长度缩为3)
  • 索引3:此时数组长度只有3,索引3已经超出了数组的有效范围,forEach直接终止遍历,剩下的2,4,6完全没被处理到

你看,原本要处理6个元素,实际只处理了3个(索引0、1、2),正好是一半;而被跳过的都是原本的偶数索引元素(2、4、6)——因为它们在前面元素被删除后前移了位置,但forEach的索引还在按原顺序推进,直接跳过了这些移位后的元素。

3. 本质总结

forEach的设计初衷就是不支持在遍历过程中修改数组结构(比如删除/添加元素),它会基于初始的数组快照来执行遍历。如果一定要在遍历中修改数组,更稳妥的方式是倒序遍历(从后往前删,不会影响未遍历的索引),或者用filter生成新数组(更符合函数式编程的无副作用原则)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:11:12