遍历对象应只处理自有属性,避免原型链干扰:用hasownproperty过滤for...in;object.keys()获取可枚举字符串键;需全覆盖时组合getownpropertynames与getownpropertysymbols。

JavaScript 中遍历对象时,默认会访问到原型链上的属性,这往往不是我们想要的。关键在于区分“自有属性”和“继承属性”,只处理对象自身定义的属性。
使用 hasOwnProperty 过滤原型属性
这是最经典、兼容性最好的方式。它能准确判断某个属性是否直接定义在对象自身上,而非从原型继承而来。
- 语法简单:
obj.hasOwnProperty(key) - 必须用对象实例调用(不能用
Object.prototype.hasOwnProperty.call避免被重写的情况) - 适用于
for...in循环中做守卫
示例:
for (let key in obj) {if (obj.hasOwnProperty(key)) {
console.log(key, obj[key]);
}
}
用 Object.keys() 获取自有可枚举属性
Object.keys() 返回一个数组,仅包含对象自身的、可枚举(enumerable: true)属性名,天然跳过原型属性和不可枚举属性。
- 返回值是数组,可配合
forEach、map等方法,更函数式 - 不包括 symbol 属性(需用
Object.getOwnPropertySymbols()补充) - 不包括不可枚举属性(如
constructor)
示例:
Object.keys(obj).forEach(key => {console.log(key, obj[key]);
});
完整自有属性遍历(含 Symbol 和不可枚举)
如果需要 100% 覆盖对象自身所有属性(包括不可枚举、Symbol 类型),应组合使用:
-
Object.getOwnPropertyNames(obj):获取所有自有属性名(字符串键,含不可枚举) -
Object.getOwnPropertySymbols(obj):获取所有自有 Symbol 属性 -
Object.getOwnPropertyDescriptor(obj, key)可进一步检查enumerable、writable等特性
示例(合并所有自有键):
const keys = [...Object.getOwnPropertyNames(obj), ...Object.getOwnPropertySymbols(obj)];keys.forEach(key => {
console.log(key, obj[key]);
});
注意 for...in 的隐式行为
for...in 会遍历整个原型链上可枚举的属性,且顺序不保证(尤其涉及数字键与字符串键混合时)。即使父类属性被设置为 enumerable: false,只要中间某层设为 true,仍可能暴露出来。
- 永远不要假设
for...in只遍历当前对象 - 避免在类实例或字面量以外的对象上直接使用(比如
Array.prototype扩展后会影响所有数组) - 现代代码优先选
Object.keys()+ 数组方法,语义清晰、不易出错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











