object.hasown(obj, prop)更安全,因它始终调用object.prototype.hasownproperty原始实现,规避了对象重写hasownproperty、object.create(null)无该方法及原型链污染三类风险,且支持symbol、明确报错、语义清晰。

直接用 Object.hasOwn(obj, prop) 替代 obj.hasOwnProperty(prop),就能更安全地确认属性是否真正属于该对象自身。
为什么 hasOwnProperty 不够可靠
它依赖对象从 Object.prototype 继承的方法,但实际中常遇到三类问题:
- 对象自己定义了
hasOwnProperty属性(比如{ hasOwnProperty: () => false }),调用后返回错误结果 - 对象通过
Object.create(null)创建,压根没有继承该方法,调用直接抛TypeError - 原型链被污染,例如
Object.prototype.hasOwnProperty = () => true,导致所有检测失效
Object.hasOwn 的核心保障
它是 ES2022 标准化引入的静态方法,从设计上绕开上述风险:
- 始终调用
Object.prototype.hasOwnProperty的原始实现,不走目标对象的原型链 - 支持字符串和 Symbol 类型的属性名,行为一致且健壮
- 对
null或undefined参数明确抛TypeError,避免静默失败 - 只检查对象自身属性(包括不可枚举属性),语义清晰、结果可预期
怎么替换成日常写法
替换非常直接,保持参数顺序和布尔返回值不变:
- ✅ 推荐写法:
if (Object.hasOwn(user, 'email')) { ... } - ❌ 风险写法:
if (user.hasOwnProperty('email')) { ... } - ⚠️ 冗余兜底(仅过渡期):
const hasOwn = Object.hasOwn || Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
注意两个常见细节
迁移时容易忽略的关键点:
-
Object.hasOwn(null, 'key')会立即抛错,如需兼容非对象值,应先做类型判断:obj != null && typeof obj === 'object' - 传入 Symbol 必须是原始值,不能传字符串描述:
Object.hasOwn(obj, Symbol('id'))✅,Object.hasOwn(obj, 'Symbol(id)')❌










