for-in循环用于遍历对象及其原型链上可枚举属性的字符串键名,不保证顺序,会遍历继承属性;需用hasownproperty过滤以确保仅自身属性,不适合数组等类数组对象,现代推荐object.keys()或object.entries()替代。

for-in 循环专门用于遍历对象的可枚举自身和继承属性的键名(即字符串形式的属性名),但它不适用于数组或类数组对象的数值索引遍历。
for-in 的基本语法和执行逻辑
for-in 会依次访问对象及其原型链上所有可枚举(enumerable: true)的属性名,顺序不保证(尤其在不同 JS 引擎中可能不同),且只返回字符串类型的键名。
- 语法:
for (let key in obj) { ... },其中key是每次迭代得到的属性名(字符串) - 它会遍历对象自身的可枚举属性,也会遍历从原型继承来的可枚举属性
- 不会遍历不可枚举属性(如
Object.prototype.toString默认不可枚举)
只遍历对象自身属性:用 hasOwnProperty 过滤
为避免意外遍历到原型上的属性(比如自定义了 Object.prototype 的方法),推荐配合 hasOwnProperty 使用:
const obj = { a: 1, b: 2 };
Object.prototype.customMethod = function() {}; // 不推荐,仅作演示
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(key); // 只输出 'a', 'b'
}
}
-
obj.hasOwnProperty(key)返回布尔值,判断该属性是否为对象自身属性(非继承) - 这是使用 for-in 最常见的安全写法
注意避开常见陷阱
for-in 不适合遍历数组、Map、Set 或类数组对象;它也不区分数据属性和访问器属性(getter/setter),只要可枚举就会被列出。
- 数组下标会被当作字符串处理(
"0","1"),但若数组有额外可枚举属性(如arr.name = "list"),也会被遍历到 - Symbol 类型的键名不会被 for-in 遍历(需用
Object.getOwnPropertySymbols()) - ES6+ 更推荐用
Object.keys()+for-of或Object.entries()替代 for-in,语义更清晰、可控性更强
替代方案推荐(现代写法)
如果目标只是遍历对象自身的可枚举字符串键名,优先考虑:
-
for (const key of Object.keys(obj))—— 返回数组,顺序确定,只含自身可枚举字符串键 -
for (const [key, value] of Object.entries(obj))—— 同时拿到键和值,更直观 - 需要包含不可枚举或 Symbol 键时,再考虑
Object.getOwnPropertyNames()或Reflect.ownKeys()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











