Object.hasOwn是ES2022引入的安全替代方案,用于准确判断对象自身是否拥有某属性而不查找原型链;它规避了hasOwnProperty在null原型对象或被覆盖时的错误,统一语法、支持Symbol、返回布尔值且无副作用。

直接调用 obj.hasOwnProperty(prop) 看似简单,实则存在两个关键风险:对象可能没有这个方法,或者这个方法已被篡改。现代开发中应优先使用 Object.hasOwn(obj, prop) 替代它。
对象可能根本没有 hasOwnProperty 方法
用 Object.create(null) 创建的对象不继承自 Object.prototype,因此自身不含 hasOwnProperty 方法:
- 执行
obj.hasOwnProperty('x')会直接抛出TypeError: obj.hasOwnProperty is not a function - 正确做法是改用
Object.hasOwn(obj, 'x'),它不依赖对象自身的原型链,始终安全可用 - 兼容旧环境可降级为
Object.prototype.hasOwnProperty.call(obj, 'x'),但写法冗长
对象可能覆盖了自身的 hasOwnProperty
JavaScript 不保护该方法名,任何对象都可将其设为任意值(函数、字符串、null 等):
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
const bad = { hasOwnProperty: false, a: 1 };→bad.hasOwnProperty('a')返回false(不是布尔判断结果,而是取属性值) -
const evil = { hasOwnProperty() { return Math.random() > 0.5 } };→ 检测结果不可预测 -
Object.hasOwn(evil, 'a')完全不受影响,始终返回准确的布尔值
别和 in 操作符混淆
in 查的是“自身 + 整条原型链”,hasOwnProperty 和 Object.hasOwn 只查“对象自身”:
立即学习“Java免费学习笔记(深入)”;
-
'toString' in {}是true(来自Object.prototype),但Object.hasOwn({}, 'toString')是false - 若需区分继承属性与自有属性,必须用后者;仅用
in容易误把原型方法当作目标对象的数据属性 - 遍历对象时漏掉这层判断,很可能把
Object.prototype.log = () =>{}这类意外添加的方法也当作业务属性处理
其他常见疏忽
即使避开上述陷阱,仍有几个细节容易忽略:
-
Object.hasOwn对非对象参数(如字符串、数字、null、undefined)会抛TypeError,使用前建议加类型防护:obj != null && typeof obj === 'object' - 不要对
Map或Set使用它——它们有自己的.has()方法,语义和行为完全不同 - TypeScript 项目需确保
lib配置为es2022或更高,否则类型定义中不包含Object.hasOwn

















