反向 for 循环是遍历数组并删除元素的首选方法,因其从末尾开始遍历,删除不影响未访问索引;while 循环次之,通过手动控制索引确保不遗漏;应避免 forEach 或正向 for 中直接 splice,以防跳过相邻项。

在 JavaScript 中遍历数组时直接删除元素,最容易出错的地方就是跳过相邻项。根本原因是:数组长度和索引会动态变化,而多数遍历方式(如 forEach、正向 for)按初始索引顺序执行,不会自动适应结构变更。
反向 for 循环(就地修改首选)
从最后一个索引开始往前走,删除操作不影响前面未访问的索引,逻辑清晰、性能好、无需额外变量:
- 写法简单:
for (let i = arr.length - 1; i >= 0; i--) { if (shouldDelete(arr[i])) arr.splice(i, 1); } - 适合批量删除且必须修改原数组的场景,比如清理任务列表、移除 DOM 对应数据等
- 注意:删除后数组变短,但
i仍递减,所以不会越界或遗漏
while 循环(手动控索引更稳妥)
用 while 显式管理下标,只在不删除时才推进,确保每个位置都被检查一次:
- 典型写法:
let i = 0; while (i - 比正向
for+i--更易读、更少出错,尤其适合条件复杂或需混合操作(删+改)的情况 - 适用于需要精细控制流程、或与其他逻辑嵌套的业务代码中
filter() 创建新数组(推荐函数式写法)
不修改原数组,而是生成过滤后的新数组并重新赋值,无副作用、可预测性强:
- 一行解决:
arr = arr.filter(item => !shouldDelete(item)); - 符合现代 JS 实践,利于调试、测试和状态管理(如 React 中避免意外突变)
- 注意:若其他变量引用了原数组,它们不会自动更新;DOM 同步需单独处理
这些方式要避开
以下做法容易导致漏删,应明确避免:
-
forEach中调用splice、pop或shift—— 迭代器基于初始快照,删除后索引偏移,必然跳项 - 正向
for循环配splice(i, 1)且不调整i—— 第二个连续匹配项会被跳过 - 用
delete arr[i]—— 元素变undefined,但数组长度不变,遍历时仍占位,语义不清


















