object.hasown 是 es13 引入的静态方法,用于准确判断对象自身是否拥有某属性,避免 hasownproperty 被重写或无原型对象报错的问题,支持 symbol 和数字键,且只检查自有属性不查原型链。

Object.hasOwn 是 ECMAScript 2022(ES13)正式引入的标准方法,用于安全、准确地判断对象自身是否拥有某个属性(即该属性存在于对象自身的属性键中,而非原型链上)。它替代了过去常用但存在缺陷的 obj.hasOwnProperty(prop),是规范化对象属性存取逻辑的重要一环。
为什么需要 Object.hasOwn 而不是 hasOwnProperty?
传统写法 obj.hasOwnProperty(prop) 有两个主要问题:
- 如果对象自身重写了
hasOwnProperty方法(例如{ hasOwnProperty: () => false }),调用会失效或抛错; - 若对象是
Object.create(null)创建的“无原型对象”,它根本就没有hasOwnProperty方法,直接调用会报TypeError。
Object.hasOwn(obj, prop) 是静态方法,不依赖对象原型,完全绕过上述风险,语义更清晰、行为更可靠。
如何用 Object.hasOwn 替代旧模式
只需将原来基于实例的方法调用,改为统一的静态函数调用:
- ❌
obj.hasOwnProperty('x') - ✅
Object.hasOwn(obj, 'x') - ✅
Object.hasOwn(obj, Symbol('key'))(支持 symbol 类型键) - ✅
Object.hasOwn(obj, 42)(数字键会被自动转为字符串,与 in 操作符一致)
它和 prop in obj 的区别在于:后者会查找整个原型链,而 Object.hasOwn 只查对象自身——这是关键语义差异,不可混淆。
在属性存取器(getter/setter)场景中的应用
定义属性描述符或使用 Object.defineProperty 时,常需先确认目标属性是否已存在,避免覆盖或误判。此时 Object.hasOwn 提供了干净的前置检查:
- 设置前判断:
if (!Object.hasOwn(obj, 'value')) Object.defineProperty(obj, 'value', { ... }) - 封装安全的赋值函数:
function safeSet(obj, key, val) { if (Object.hasOwn(obj, key)) return false; obj[key] = val; return true; } - 配合 Proxy 使用:
handler.has或handler.get中,用Object.hasOwn(target, prop)精确区分自有属性与继承属性,避免代理逻辑被原型干扰。
兼容性与渐进式采用
现代浏览器(Chrome 93+、Firefox 92+、Safari 16.4+)及 Node.js 16.9+ 均原生支持。如需兼容旧环境,可用简单 polyfill:
Object.hasOwn ??= Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
注意:此 polyfill 在 Object.create(null) 上仍有效,因为 call.bind 绕过了实例方法缺失的问题。但在生产环境中,建议优先使用原生实现,并通过构建工具(如 Babel)按需处理兼容性。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











