Object.hasOwn 是 ES2022 引入的安全准确判断对象自有属性的方法,替代易出错的 hasOwnProperty 和不严谨的 in 操作符,始终调用原始实现、支持 Symbol、仅查自身属性且对非对象参数抛 TypeError。

Object.hasOwn 是 ES2022 引入的原生方法,用于**安全、准确地判断对象自身是否拥有指定属性**,替代过去容易出错的 obj.hasOwnProperty(prop) 和不严谨的 prop in obj。
为什么需要 Object.hasOwn?
传统方式存在明显缺陷:
-
obj.hasOwnProperty会被原型链上同名方法覆盖(比如某个对象自己定义了hasOwnProperty: null或hasOwnProperty() { return false; }),导致检测失效; -
prop in obj会查找整个原型链,无法区分“自有属性”和“继承属性”; -
obj[prop] !== undefined无法处理值为undefined的合法属性,且会触发 getter; - 手动绑定
Object.prototype.hasOwnProperty.call(obj, prop)冗长且易忘。
Object.hasOwn 的正确用法
语法简洁,语义明确:
Object.hasOwn(obj, 'key') // true / false
它始终从 Object.prototype 调用原始实现,不受目标对象干扰:
立即学习“Java免费学习笔记(深入)”;
- 即使
obj.hasOwnProperty被重写或删除,Object.hasOwn(obj, 'key')仍可靠; - 只检查对象自身属性(不含原型链),等价于
Object.prototype.hasOwnProperty.call(obj, key),但更直观; - 支持 Symbol 类型键:
Object.hasOwn(obj, Symbol('id')); - 对
null或undefined参数会抛出 TypeError,符合预期——它本就只适用于对象。
常见误用与注意事项
注意这些边界情况:
- 不支持非对象参数:传入字符串、数字等原始值会报错,需先确保是对象(可用
obj != null && typeof obj === 'object'防御); - 不适用于 Map/Set:它们有自己的
has()方法,不要混用; - 不能替代
Reflect.has:后者行为类似in操作符(查原型链),用途不同; - TypeScript 中需确保
lib设置为es2022或更高,否则类型定义可能缺失。
迁移建议
逐步替换老旧写法:
- 把
obj.hasOwnProperty(key)直接改为Object.hasOwn(obj, key); - 若原逻辑依赖原型链检查(如判断是否可被 for...in 遍历到),请改用
key in obj或Reflect.has(obj, key); - 构建工具(如 Babel)暂不默认转换,生产环境需确认目标平台支持(Chrome 93+/Firefox 92+/Safari 15.4+,Node.js 16.9+);
- 兼容老环境时,可用简单 polyfill:
if (!Object.hasOwn) {
Object.hasOwn = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
}


















