for...in 不适合遍历数组,因其会枚举对象可枚举属性(含原型链);应改用 for...of、forEach() 等数组专用方法,它们只访问自身索引元素,避免原型链干扰。

JavaScript 中 for...in 循环**本就不适合遍历数组**,它设计初衷是枚举对象的可枚举属性(包括原型链上的),所以天然会访问到继承来的属性。要避免遍历到原型链属性,最直接有效的方式是**根本不用 for...in 遍历数组**,改用更安全、语义更明确的方法。
优先使用数组专用迭代方法
现代 JavaScript 提供了专为数组设计的遍历方式,它们只访问数组自身的索引元素,完全绕过原型链:
-
for...of:遍历数组元素值,不关心索引,也不触碰原型属性 -
forEach()、map()、filter()等高阶函数:只作用于数组自身拥有的数值索引项 -
传统
for循环(for (let i = 0; i ):精确控制索引范围,完全避开属性枚举逻辑
如果必须用 for...in(极不推荐),需手动过滤
仅在特殊兼容场景或处理“类数组对象”时可能遇到,此时必须加判断:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 用
Object.prototype.hasOwnProperty.call(arr, key)确保属性属于数组自身(不是从Array.prototype或Object.prototype继承) - 额外检查
key是否为有效数组索引(如/^\d+$/.test(key) && key < arr.length),因为for...in还可能遍历到非数字键(如自定义属性arr.custom = 'x')
警惕污染原型链的风险
即使你写了 hasOwnProperty 检查,若有人执行了类似 Array.prototype.myMethod = function(){} 的操作,且该方法是可枚举的(ES5 默认不可枚举,但可通过 Object.defineProperty 显式设为可枚举),for...in 仍可能捕获到它——而 hasOwnProperty 无法拦截这种原型上的可枚举属性。这说明问题根源不在“怎么过滤”,而在“不该用这个工具干这事”。
立即学习“Java免费学习笔记(深入)”;
一句话总结
不要用 for...in 遍历数组;用 for...of、forEach 或传统 for 循环;若因历史代码必须保留 for...in,则务必配合 hasOwnProperty 和索引有效性校验,但这是权宜之计,不是最佳实践。

















