for...in 默认遍历自身及原型链上可枚举属性,需用 hasownproperty() 过滤;更推荐 object.keys() + for...of,语义清晰且无原型干扰。

使用 for...in 遍历对象时,默认会遍历**自身可枚举属性 + 原型链上所有可枚举属性**。要只遍历对象自身的属性,必须配合 hasOwnProperty() 方法做过滤。
用 hasOwnProperty() 过滤原型链属性
这是最常用、最可靠的方式。它能准确区分属性是否直接定义在对象本身上:
const parent = { a: 1, b: 2 };
const child = Object.create(parent);
child.c = 3;
child.d = 4;
for (const key in child) {
if (child.hasOwnProperty(key)) {
console.log(key); // 只输出 'c', 'd'
}
}
注意:不能依赖 propertyIsEnumerable()
propertyIsEnumerable() 虽然也判断自身属性,但它还会额外检查属性的 enumerable 标志位。如果某个自有属性被设为不可枚举(如通过 Object.defineProperty 设置 enumerable: false),for...in 本来就不会访问到它,再用 propertyIsEnumerable 就多余且可能误导。所以优先用 hasOwnProperty。
替代方案:用 Object.keys() + for of(推荐)
如果不需要兼容非常老的环境(如 IE8 及以下),更现代、更安全的做法是避免 for...in:
-
Object.keys(obj)返回数组,只包含对象**自身可枚举字符串键** - 配合
for...of或forEach使用,语义清晰、无原型干扰
for (const key of Object.keys(child)) {
console.log(key); // 同样只输出 'c', 'd'
}
扩展:想同时排除 Symbol 属性?
Object.keys() 和 for...in 都只处理字符串键,天然忽略 Symbol 类型的键。若需遍历所有自有键(含 Symbol),可用:
-
Object.getOwnPropertyNames(obj)→ 字符串键(含不可枚举) -
Object.getOwnPropertySymbols(obj)→ Symbol 键 -
Reflect.ownKeys(obj)→ 合并两者(ES6+)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











