object.hasown()是最稳妥的自有属性检查方案,它明确判断对象自身是否定义某属性,不依赖原型链、不受undefined值干扰、支持symbol和不可枚举属性,且对null/undefined输入抛错避免隐式转换。

用 Object.prototype.hasOwnProperty.call(obj, key) 是最稳妥的语义化方案,它明确表达“检查该对象自身是否定义了这个属性”,不依赖原型链,也不受属性值真假值干扰。
为什么不用 obj.key !== undefined 或 key in obj
前者无法区分属性是否存在和属性值恰好为 undefined;后者会命中继承属性,语义上是“是否可访问”,而非“是否自有”。比如:
-
{a: undefined}.a !== undefined→false,但属性a确实存在且是自有属性 -
'toString' in {}→true,但toString来自Object.prototype,不是自有属性
推荐写法:hasOwn(obj, key) 封装(ES2022+ 可直接用 Object.hasOwn())
ES2022 正式引入 Object.hasOwn(),它是 hasOwnProperty 的现代替代,更安全、更语义清晰,且能正确处理 null/undefined 输入(抛出 TypeError,而非静默失败):
- ✅
Object.hasOwn({a: 1}, 'a')→true - ✅
Object.hasOwn(Object.create({b: 2}), 'b')→false(只查自身) - ❌
Object.hasOwn(null, 'a')→ 抛错,避免隐式转换陷阱
若需兼容旧环境,可封装一层:
const hasOwn = Object.hasOwn || ((obj, key) => Object.prototype.hasOwnProperty.call(obj, key));
注意边界情况:Symbol 属性与不可枚举属性
hasOwn(含 hasOwnProperty 和 Object.hasOwn)对 Symbol 类型键完全支持,且不区分属性是否可枚举——只要该属性存在于对象自身,就返回 true:
-
const sym = Symbol('s'); const o = {[sym]: 42}; Object.hasOwn(o, sym)→true -
Object.defineProperty({}, 'hidden', {value: 1, enumerable: false})→Object.hasOwn(...)仍返回true
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











