object.hasown 是判断属性是否为对象自有属性最安全直接的方式,它不查原型链、不依赖 hasownproperty、支持 symbol 且兼容 null 原型对象,es2022 标准,现代环境原生支持。

用 Object.hasOwn 判断属性是否属于对象自身,是当前最安全、最直接的方式——它天然绕过原型链,只看对象自己身上有没有那个属性,不管值是 undefined、null 还是其他任何值。
为什么 Object.hasOwn 能准确区分自有属性
它专为“归属判断”设计:只要属性是对象自身定义的(哪怕通过 obj.x = undefined 显式赋值),就返回 true;如果属性来自 prototype、Object.prototype 或任何上层原型,一律返回 false。
- 不依赖
obj.hasOwnProperty,避免被覆盖或Object.create(null)场景下方法缺失的问题 - 不需要
call绑定,调用简洁:Object.hasOwn(obj, 'prop') - 对
Symbol属性同样有效
对比 Reflect.has 和 in 运算符
Reflect.has 和 in 检查的是“能否访问到”,会顺着原型链向上找:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
-
Reflect.has(obj, 'toString')→true(因为继承自Object.prototype) -
'toString' in obj→true(同上) -
Object.hasOwn(obj, 'toString')→false(不是对象自身的)
所以当你关心“这个属性是不是这个对象亲手加上的”,必须用 Object.hasOwn,而不是靠 in 或 Reflect.has。
实际使用中的典型场景
常见于需要过滤原型干扰的操作:
- 遍历对象时只处理自有属性:
for (const key of Object.keys(obj)) { ... }(Object.keys本身已内置自有属性过滤,但若用for...in,就得搭配Object.hasOwn) - 对象合并前校验来源:
if (Object.hasOwn(source, key)) target[key] = source[key]; - 防止原型污染导致的误判:
const data = Object.create(null); data.id = 123;<br>Object.hasOwn(data, 'id') // true(而 hasOwnProperty 会报错或不可用)
兼容性与替代方案
Object.hasOwn 是 ES2022 正式标准,在现代浏览器和 Node.js 16.9+ 均原生支持。如需兼容旧环境:
- 可降级为
Object.prototype.hasOwnProperty.call(obj, prop) - 不推荐直接调用
obj.hasOwnProperty(prop),因该方法可能被覆盖或在null原型对象上不存在
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










