for循环最稳妥但需防length被改;for...of简洁适合纯读取,跳过稀疏数组空位;for...in慎用于数组,遍历对象属性名且顺序不定;Object.entries()兼顾键值、可读性与安全性。

for 循环遍历数组最稳妥,但要注意 length 被修改的风险
直接用 for (let i = 0; i 是最兼容、最可控的方式,尤其适合需要索引、中途 break 或修改原数组的场景。
-
arr.length每次都重新读取,如果循环中意外push或splice数组,可能造成死循环或跳项 - 想避免重复读取长度,可提前缓存:
const len = arr.length; for (let i = 0; i - 遍历时要修改数组(比如删除满足条件的元素),推荐倒序
for (let i = arr.length - 1; i >= 0; i--),避免索引错位
for...of 遍历数组更简洁,但拿不到索引
它按顺序消费数组的 Symbol.iterator,语义清晰,适合纯读取场景。
- 不能直接获取当前项索引;需要手动计数:
let i = 0; for (const item of arr) { console.log(i++, item); } - 不支持类数组对象(如
arguments、NodeList)——除非它们有原生迭代器或已转成数组 - 遇到
undefined或稀疏数组(如[1, , 3])时,for...of会跳过空位,而传统for会访问到undefined
const arr = [1, , 3];
for (const item of arr) {
console.log(item); // 输出:1,然后是 3(跳过了空位)
}
for...in 不该用来遍历数组,但能遍历对象自有属性
for...in 枚举的是对象的**可枚举属性名**(字符串),不是值,也不保证顺序。对数组来说,它遍历的是索引字符串("0"、"1"),还可能包含原型链上的属性。
- 数组上慎用:
for...in可能遍历到意外添加的方法(如arr.customMethod = () => {}) - 对象遍历时,只拿到键名,需配合
obj[key]取值;若对象有继承属性且未设enumerable: false,也会被枚举出来 - 更安全的对象遍历方式是
Object.keys(obj).forEach(key => {...})或Object.entries(obj)
const obj = { a: 1, b: 2 };
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
console.log(key, obj[key]); // 加这层判断才相对可靠
}
}遍历对象优先用 Object.entries(),兼顾键、值和可读性
它返回一个二维数组([["key1", val1], ["key2", val2]]),天然适配 for...of 和数组方法。
立即学习“Java免费学习笔记(深入)”;
- 比
for...in + hasOwnProperty更简洁,也避免了属性枚举顺序不可靠的问题 - 支持解构:
for (const [key, value] of Object.entries(obj)) - 注意:只遍历对象自身可枚举属性,不包括
Symbol键;要包含 Symbol,请用Object.getOwnPropertySymbols()单独处理 - 性能略低于
for...in,但绝大多数业务场景无感知
有些开发者以为 for...of 能直接遍历普通对象,结果报 TypeError: obj is not iterable —— 这个错误提示其实很准确:对象默认没有 [Symbol.iterator],得靠 Object.entries() 这类显式转换来“赋予”遍历能力。










