核心区别在于是否查原型链:in 检查整个原型链上是否存在属性名,而 hasownproperty 仅检查对象自身属性;object.hasown 是更安全的现代替代方案。

核心区别就一句话:是否查原型链。
in 会顺着原型链一路往上找,只要任何一层有这个属性名,就返回 true;hasOwnProperty 只看对象自己身上有没有,原型上的再近也不认。
in 是“能不能用”,不挑出处
它回答的是:“我写 obj.key 或 obj['key'] 能不能取到值?”——不管这个 key 是自己写的、父类加的、还是往 Object.prototype 上塞的,只要最终能访问,就成立。
- 属性值是
undefined,'key' in obj依然为 true - 数组用
'0' in arr检的是索引是否存在,不是元素是否为真值 - 对
null或undefined使用会直接报错,必须确保左操作数是对象
hasOwnProperty 是“是不是我写的”
它专注回答:“这个属性名是不是我亲手挂在这个对象上的?”——哪怕原型上有个同名方法,也坚决不算。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 对
Object.create(null)创建的对象,直接调用会报错(没原型),应写成Object.prototype.hasOwnProperty.call(obj, 'key') - 它不区分可枚举或不可枚举,只要在自身属性表里登记过(比如用
Object.defineProperty设置的),就返回 true - 如果对象自己把
hasOwnProperty改成了别的值(比如obj.hasOwnProperty = null),原方法就失效了
现代推荐:用 Object.hasOwn 替代 hasOwnProperty
ES2022 引入的 Object.hasOwn(obj, 'key') 是更安全、更简洁的选择:
- 不用
call绑定,调用直截了当 - 不怕对象覆盖了
hasOwnProperty,语义更明确 - Node.js 16.9+、Chrome 93+、Firefox 91+ 等环境已稳定支持
- 老旧环境可用 polyfill 回退,或继续用
Object.prototype.hasOwnProperty.call
别用 Object.keys().includes() 做存在性判断
有人想绕开原型问题,结果写了 Object.keys(obj).includes('key'),这其实更糟:
- 每次调用都新建数组,循环中反复触发垃圾回收
- 只包含可枚举自有属性,漏掉
configurable: false或enumerable: false的字段 - 完全无法满足需要检查原型链的场景(比如判断能否调用
toString)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










