选 for、forEach 还是 for-of 取决于具体需求:需中断循环、索引、反向遍历或性能敏感时用 for;for 提供完全控制,性能最优,V8 优化好,推荐缓存 length。

选 for、forEach 还是 for-of,关键不是“哪个更高级”,而是看你要解决什么问题:需不需要中断循环?要不要索引?是否在意返回值?语义是否清晰?性能是否敏感?
需要 break/continue 或反向遍历 → 用 for
for 循环提供完全控制权。你可以随时用 break 跳出整个循环,用 continue 跳过当前项,也能轻松实现倒序遍历(i = arr.length - 1; i >= 0; i--)或步长跳跃(i += 2)。它还天然支持访问索引和原数组,适合操作多个关联数组、处理稀疏数组、或在循环中动态修改数组长度(比如边遍历边 splice)。
- 性能最优:10 万元素下通常比 forEach 快 40%–60%,V8 对其有深度内联优化
- 推荐写法:缓存
length,避免每次比较都读取属性(for (let i = 0, len = arr.length; i ) - 注意点:别在循环体里意外修改
i或arr.length,否则易陷入死循环或漏项
只做副作用操作、强调可读性 → 用 forEach
当你只需要“对每个元素执行一段逻辑”,比如打日志、发请求、更新 DOM、收集状态,且确定不会中途退出,forEach 是最贴切的选择。它的函数签名明确传递 item、index、array,语义一目了然,也天然规避了闭包索引捕获错误(箭头函数下 index 总是当前值)。
- 不能用
break或return中断;想提前退出只能抛错(不推荐)或改用some/every - 跳过稀疏数组中的空位(如
[1, , 3]中间那个undefined项不会触发回调) - 不返回有用值(固定返回
undefined),所以不能链式调用后续数组方法
要简洁语法 + 可中断 + 支持异步 → 用 for-of
for-of 是 for 循环的现代替代品,语法干净,直接解构元素,同时保留 break 和 continue 的能力。它基于迭代器协议,不仅能遍历数组,还能遍历字符串、Set、Map、生成器等所有可迭代对象,也天然兼容 await,适合写带异步操作的顺序遍历逻辑。
立即学习“Java免费学习笔记(深入)”;
- 无法直接拿到索引——需要索引时可配合
entries()(for (const [i, item] of arr.entries())) - 性能介于 for 和 forEach 之间,比 forEach 快,但略慢于优化后的 for
- 不遍历原型属性,也不受数组是否稀疏影响,行为稳定


















