for...in 不适合遍历数组索引,因其枚举所有可枚举字符串键(含非数字属性、原型链属性),顺序不保证且 key 为字符串,易致隐式转换错误和逻辑异常;应使用 for、for...of、forEach 等专用数组遍历方式。

for...in 不适合遍历数组索引,它本意是枚举对象的可枚举属性名(包括继承的),对数组会遍历所有可枚举的键(含非数字属性、原型链上的属性),顺序也不保证,极易出错。
for...in 遍历数组时实际做了什么
它把数组当作普通对象处理,逐个返回其所有可枚举字符串键,包括:
- 数组索引(如 "0"、"1"、"2")——但以字符串形式返回
- 手动添加的非数字属性(如
arr.name = "myList"→ 返回 "name") - 原型上新增的可枚举属性(如给
Array.prototype加了first方法且未设为不可枚举) - 稀疏数组中缺失的索引不会出现,但无法预测遍历顺序(尤其在旧引擎中)
典型隐患示例
以下代码看似正常,实则脆弱:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
arr.custom = "extra";
Array.prototype.hello = function() {}; // 可枚举时也会被遍历
for (let key in arr) {
console.log(key, arr[key]); // 输出:'0' 10, '1' 20, '2' 30, 'custom' 'extra', 'hello' [Function]
}
结果混入了非索引项,key 是字符串,若直接用于算术(如 key + 1)易引发隐式转换错误;更严重的是,一旦依赖顺序(如求和、映射),行为不可靠。
立即学习“Java免费学习笔记(深入)”;
正确遍历数组索引的替代方案
-
for 循环(传统):最直接、高效、可控,明确使用数值索引
let i = 0; i -
for...of 循环:遍历元素值;配合
entries()可同时获取索引和值:for (let [i, val] of arr.entries()) { ... } -
forEach / map / for-of + keys():需索引时优先用
arr.keys()(返回索引迭代器)或arr.entries() - 避免修改数组原型,或确保新增方法设为
enumerable: false
什么情况下 for...in 才该用
仅用于遍历纯对象(plain object)的自有可枚举属性,且你明确需要键名(字符串)、不关心顺序、也不涉及数组逻辑。例如配置对象、字典映射等场景。对数组,请坚定选择 for、for...of 或数组方法。

















