应使用 Object.hasOwn(obj, key) 替代 hasOwnProperty,因其不受属性覆盖和环境污染影响,ES2022 标准方法更安全可靠;for-in 中必须配合该判断才能准确筛选自有属性。

直接用 Object.hasOwn(obj, key) 在 for-in 循环中判断,就能准确区分自有属性和继承属性,避免误处理原型链上的属性。
为什么不能只靠 hasOwnProperty
obj.hasOwnProperty(key) 看似可用,但存在两个隐患:一是如果对象自身定义了同名方法(比如 { hasOwnProperty: () => false }),就会被覆盖失效;二是它不是严格模式下的安全方法,在某些极端场景下可能被污染或屏蔽。Object.hasOwn 是 ES2022 正式引入的静态方法,始终可靠,推荐替代 hasOwnProperty。
正确写法:在 for-in 中搭配 Object.hasOwn
只需在循环体内加一层判断,保留自有属性,跳过继承属性:
const parent = { a: 1, b: 2 };
const child = Object.create(parent);
child.c = 3;
child.d = 4;
<p>for (const key in child) {
if (Object.hasOwn(child, key)) {
console.log(key, child[key]); // 输出 c 3 和 d 4,不输出 a、b
}
}常见误用与注意事项
-
不要省略判断:
for-in天然遍历整个原型链,不加过滤会拿到所有可枚举属性 -
不能依赖
Object.keys替代:虽然Object.keys只返回自有可枚举属性,但它是一次性获取数组,无法用于需要逐个处理、中途 break/continue 或异步操作的场景 -
注意属性可枚举性:
Object.hasOwn只判断是否为自有属性,不关心是否可枚举;若还需过滤掉enumerable: false的自有属性,得额外用Object.getOwnPropertyDescriptor -
兼容性考虑:Node.js ≥16.9 / Chrome ≥93 / Firefox ≥97 支持;旧环境可用
Object.prototype.hasOwnProperty.call(obj, key)降级,但不如Object.hasOwn简洁安全
进阶:封装成可复用的自有属性迭代器
如果项目中多次需要该逻辑,可以封装一个生成器函数:
立即学习“Java免费学习笔记(深入)”;
function* ownKeys(obj) {
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
yield key;
}
}
}
<p>// 使用
for (const key of ownKeys(child)) {
console.log(key, child[key]);
}


















