hasownproperty易被覆盖或缺失,应统一用object.prototype.hasownproperty.call(obj, key);它只查自身属性,in操作符查整个原型链;for...in需加此判断过滤原型属性;es2022新增object.hasown()更安全简洁。

hasOwnProperty 看似简单,但实际使用中容易踩几个隐蔽的坑。最核心的问题是:它不是语言层面的安全运算符,而是对象身上的一个普通方法——既可能被覆盖,也可能根本不存在。
误区一:直接调用 obj.hasOwnProperty() 可能报错或返回错误结果
对象可以随意覆盖自己的 hasOwnProperty 方法,甚至设为 null 或 false,这时调用就失效了:
- 覆盖后始终返回
false:比如obj.hasOwnProperty = () => false - 对
Object.create(null)创建的对象直接调用会报错:TypeError: obj.hasOwnProperty is not a function
✅ 修正方式:统一用 Object.prototype.hasOwnProperty.call(obj, key)。它绕过对象自身的方法,从原型上安全调用。
误区二:混淆 hasOwnProperty 和 in 操作符
两者检查范围完全不同:
-
in查的是“自身 + 整条原型链”,只要属性存在就返回true -
hasOwnProperty只查“对象自身是否定义了该属性”,不看原型链
例如,所有对象都能访问 toString,但 obj.hasOwnProperty('toString') 几乎总是 false(除非你手动在对象上加了这个属性)。
误区三:在 for...in 循环中漏掉 hasOwnProperty 判断
for...in 会遍历包括原型链上的**可枚举属性**。如果没加判断,就可能把 Object.prototype 上被意外添加的方法(如 gender、log)也当作目标对象的属性处理。
✅ 正确写法:
for (let key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
console.log(key, obj[key]);
}
}
误区四:忽略 ES2022 新增的更优替代方案
现代 JavaScript 已引入 Object.hasOwn()(2022 年标准化),它语义清晰、无需绑定、天然防覆盖:
- ✅
Object.hasOwn(obj, 'key')—— 推荐用于新项目 - ⚠️ 兼容旧环境可降级:
Object.hasOwn ?? Object.prototype.hasOwnProperty.call
相比 hasOwnProperty,它不依赖对象自身的继承链,也不怕被覆盖,还更易读。











