object.hasown(obj, prop)是es2022引入的安全替代方案,始终调用原始hasownproperty实现,规避原型链干扰、方法被重写及null/undefined报错等问题,语义清晰且仅查自身属性。

直接用 Object.hasOwn(obj, prop) 替代 obj.hasOwnProperty(prop),就能避开原型链干扰、方法被重写或对象无原型等隐患,检测结果更可靠。
为什么 hasOwnProperty 不够安全
传统方式依赖对象自身继承的 hasOwnProperty 方法,但存在三类典型风险:
- 对象自己重写了该方法(比如
{ hasOwnProperty: () => false }),导致始终返回错误结果 - 对象通过
Object.create(null)创建,压根没继承hasOwnProperty,调用直接报TypeError - 手动用
Object.prototype.hasOwnProperty.call(obj, prop)虽然安全,但写法冗长、易遗漏、可读性差
Object.hasOwn 的核心优势
它是 ES2022 标准化引入的静态方法,从设计上就规避了上述问题:
- 始终调用
Object.prototype.hasOwnProperty的原始实现,不走目标对象的原型链 - 支持 Symbol 类型属性名,和
hasOwnProperty行为一致但更健壮 - 只检查对象自身属性,不包含继承属性,语义清晰
- 对
null或undefined参数会明确抛出TypeError,避免静默失败
实际替换操作与注意事项
迁移成本极低,只需改写调用形式,并留意环境兼容性:
- 把
obj.hasOwnProperty('name')直接换成Object.hasOwn(obj, 'name') - 现代环境(Chrome 93+、Firefox 92+、Safari 15.4+、Edge 93+、Node.js 16.9+)已原生支持
- 需兼容旧环境时,加一段轻量 polyfill:
if (!Object.hasOwn) {<br> Object.hasOwn = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);<br>} - TypeScript 项目中,确保
tsconfig.json的"lib"包含"es2022"或更高版本
什么场景下尤其推荐使用
在数据来源不可控、结构动态性强的环节,安全收益最明显:
- 校验用户提交的表单数据是否包含必填字段(如
Object.hasOwn(userData, 'email')) - 处理第三方 SDK 返回的对象,避免其内部篡改原型方法影响判断
- 遍历配置对象前,确认某配置项是否显式设置(而非继承默认值)
- 配合 ESLint 的
no-prototype-builtins规则,自动拦截不安全调用










