hasownproperty 仅检测对象自身属性,忽略原型链上的所有属性;它不关心属性的可枚举性、可写性或是否为 getter,只要属性直接定义在对象上即返回 true;常与 for-in 配合过滤原型属性,推荐优先使用 object.hasown 替代。

hasOwnProperty 的作用不是“区分”原型属性,而是**明确拒绝原型属性**——它只认对象自己身上的属性,对原型链上的一切一概不认。
它只回答一个问题:这个 key 是不是这个对象“亲手写的”?
只要属性是直接定义在对象实例上(比如 this.name = 'Alice'、obj.x = 1、{a: 1} 或 Object.defineProperty(obj, 'b', {...})),hasOwnProperty 就返回 true;哪怕这个属性在原型上也能被访问到,只要没直接挂在当前对象上,就返回 false。
-
person.name→person.hasOwnProperty('name')是 true(构造函数里this.name赋值) -
person.species→person.hasOwnProperty('species')是 false(定义在Person.prototype上) -
person.toString()→person.hasOwnProperty('toString')是 false(来自Object.prototype)
它和属性是否可枚举、是否可写、有没有 getter 完全无关
hasOwnProperty 不看属性描述符。即使你用 Object.defineProperty 把一个属性设成 enumerable: false 或 writable: false,只要它在对象自身上,hasOwnProperty 依然返回 true。
- 不可枚举的自有属性:
Object.defineProperty(obj, 'hidden', { value: 42, enumerable: false })→obj.hasOwnProperty('hidden')仍是 true - getter 属性:
Object.defineProperty(obj, 'computed', { get() { return 'ok'; } })→obj.hasOwnProperty('computed')也是 true
它必须配合 for-in 才能真正“过滤掉”原型属性
for-in 会把所有可枚举属性(包括原型上的)都列出来,而 hasOwnProperty 是唯一轻量、标准、语义清晰的过滤手段:
- 错误写法:
for (let k in obj) { console.log(k); }→ 可能输出toString、valueOf等 - 正确写法:
for (let k in obj) { if (obj.hasOwnProperty(k)) { /* 处理自身属性 */ } }
更现代、更安全的替代方案:Object.hasOwn
如果你需要稳定判断自有属性,尤其面对可能被篡改或无原型的对象(如 Object.create(null)),推荐直接用 Object.hasOwn(obj, key):
- 不用担心对象覆盖了
hasOwnProperty方法 - 无需手动绑定
call,语法更简洁 - 语义更直白:“obj 是否拥有 own 属性 key?”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











