hasownproperty()仅判断属性是否为对象自身所有,不关心是否原生:显式添加即返回true,原型继承则返回false;object.keys()和object.hasown()是更安全的现代替代方案。

JavaScript 中 hasOwnProperty 不会把原生对象(如 Object.prototype 上的 toString、valueOf、constructor 等)当作对象自身的属性,它只认“直接挂载在该对象上”的属性。
它只看属性归属,不看属性是否原生
hasOwnProperty 的判断逻辑与“原生与否”无关,只取决于属性是否属于当前对象自身:
- 哪怕属性名是标准原生方法名(如
"toString"),只要它被显式添加到实例上,就返回true - 哪怕属性值是
null或undefined,只要键存在且是自有属性,仍返回true - 如果对象没定义该键,哪怕原型链上有同名原生方法(如
Object.prototype.toString),也返回false
常见原生属性在 hasOwnProperty 下的表现
以空对象为例:
const obj = {};
-
obj.hasOwnProperty('toString')→false(toString来自Object.prototype) -
obj.hasOwnProperty('hasOwnProperty')→false(同理,也是继承来的) -
obj.toString = function() {};后,obj.hasOwnProperty('toString')→true -
obj.constructor = null;后,obj.hasOwnProperty('constructor')→true(已覆盖为自有属性)
为什么不能依赖 hasOwnProperty 判断“是否安全”
它只回答“是不是我自己的”,不回答“这个属性是否可信或可用”:
- 对象可能自己定义了
hasOwnProperty: false,导致原生方法被遮蔽 - 原型污染后,
Object.prototype.customLog可能被遍历出来,但hasOwnProperty仍返回false(因它不属于实例) - 不可枚举属性(如
Object.defineProperty(obj, 'hidden', { value: 1, enumerable: false }))不会被for...in遍历,hasOwnProperty虽返回true,但常规遍历根本遇不到
更现代、更稳妥的替代方式
若目标是获取“干净的自有可枚举属性”,优先用内置方法而非手动过滤:
-
Object.keys(obj):返回字符串键数组,天然排除原型属性和不可枚举项 -
Object.entries(obj):直接拿到键值对,同样只含自有可枚举属性 -
Object.hasOwn(obj, key)(ES2022):比hasOwnProperty更健壮,不受对象自身同名属性遮蔽影响
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











