应使用 object.hasown()(es2022+ 推荐)或 object.prototype.hasownproperty.call()(兼容旧环境)过滤 for...in 遍历中的继承属性,因 for...in 会遍历原型链上所有可枚举属性,导致意外行为;object.keys() 更简洁,但不包含 symbol 属性。

在 JavaScript 中遍历对象时,用 Object.hasOwn()(推荐)或 hasOwnProperty()(兼容旧环境)可以准确过滤掉继承自原型链的属性,只处理对象自身的可枚举属性。
为什么不能只靠 for...in?
for...in 会遍历对象自身及原型链上所有可枚举属性。如果父类或 Object.prototype 上添加了方法(比如通过 Object.prototype.method = ...),它们也会被遍历到,容易引发意外行为或错误。
用 Object.hasOwn() 过滤(ES2022+ 推荐)
Object.hasOwn(obj, key) 是现代、安全、可读性高的方式,它不依赖对象自身的 hasOwnProperty 方法(避免被覆盖或丢失)。
- 直接传入对象和属性名,返回布尔值
- 即使对象的
hasOwnProperty被重写或设为undefined,它依然可靠 - 比
obj.hasOwnProperty(key)更健壮
示例:
const parent = { shared: 'I am inherited' };
const obj = Object.create(parent);
obj.own = 'I am own';
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
console.log(key); // 只输出 'own'
}
}
兼容老环境:用 obj.hasOwnProperty()(需谨慎)
若需支持 IE 或早期 Node.js 版本,可用 obj.hasOwnProperty(key),但要注意:
- 必须确保
obj有该方法(绝大多数对象都有,除非显式删除或原型被篡改) - 不能对
null或undefined调用,否则报错 - 更稳妥写法是借用
Object.prototype.hasOwnProperty.call(obj, key)
稳妥写法示例:
for (const key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
console.log(key);
}
}
替代方案:Object.keys() + for...of(更简洁)
如果只需遍历自身可枚举属性,无需判断条件,Object.keys() 是最直接的选择:
- 它天然只返回对象自身的可枚举字符串键
- 返回数组,可配合
for...of、forEach等使用 - 不涉及原型链,也无需手动过滤
示例:
Object.keys(obj).forEach(key => {
console.log(key, obj[key]);
});
注意:Object.keys() 不包含 Symbol 属性;如需包括 Symbol,可用 Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj))。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











