改项目上一个遗留的 bug 时,“不小心”掉进了数组循环删除的坑,之前的开发中其实有解决过这类问题,为加深印象,特意再手打一次。
实例
假设有如下一个数组:
1 | let arr = [ |
现在需要循环删除其中name
为no
的对象,错误示范如下:
1 | for (let index = 0; index < arr.length; index++) { |
错误分析:
- 当循环到 index 为 2,id 为 3 的符合条件的对象时,从 length 为 6 的
arr
数组中删除了该对象,则arr
的 length - 1 - 此时原先 index 为 3 的应该匹配的对象因为数组 length 变化跑到了 index 为 2 的位置,而循环跳过了该对象,接着去判断此时 index 为 3,id 为 5 的对象,不匹配,继续进行循环
- index 为 4,id 为 6 的对象被删除
- 循环结束
可以看出,主要的问题出在删除操作改变了原数组
解决方案
- 逆向循环不考虑 length 减少带来的 index 错乱
1 | for (let index = arr.length - 1; index >= 0; index--) { |
- 把数组看成队列巧妙处理
1 | for (let index = 0; index < arr.length; index++) { |
- 重置 index 值,获得正确的迭代顺序
1 | for (let index = 0; index < arr.length; index++) { |