object.hasown 是 es2022 引入的安全判断自有属性的方法,替代 hasownproperty,支持 symbol 键、不依赖原型链、防污染,适用于校验、遍历过滤、默认值设置及解构防护等场景。

Object.hasOwn 是 ES2022 正式引入的静态方法,专为安全、准确判断对象“自有属性”而设计。它不依赖原型链、不会被对象自身属性覆盖、支持 Symbol 键,且在 Chrome 93+、Firefox 92+、Safari 15.4+、Node.js 16.9+ 中原生可用。只要目标环境满足,就应默认替换所有 obj.hasOwnProperty(prop) 场景。
处理不可信数据时避免原型污染
用户输入、第三方 API 返回或 JSON 解析结果可能被恶意构造——比如覆盖 hasOwnProperty 方法,或使用 Object.create(null) 创建无原型对象。传统写法会直接报错或返回错误结果。
-
风险写法:
data.hasOwnProperty('email')→ 若data = { hasOwnProperty: false, email: 'a@b.com' },调用报错 -
安全写法:
Object.hasOwn(data, 'email')→ 始终调用原始实现,返回true - 常见于表单提交校验、Webhook 数据解析、低代码平台配置解析等场景
遍历对象时精准过滤自有属性
配合 for...in 循环时,in 操作符会命中原型上的方法(如 toString、constructor),而 Object.keys() 虽只返回自有可枚举属性,但无法覆盖不可枚举属性检查需求。
- 正确过滤:
for (const key in obj) { if (Object.hasOwn(obj, key)) { /* 处理自有属性 */ } } - 比
Object.prototype.hasOwnProperty.call(obj, key)更简短、语义更清晰 - 适用于深克隆前的键存在性判断、对象扁平化工具、运行时字段白名单校验
配置对象兜底与解构前防护
配置项常需“若未显式设置则赋予默认值”,或解构前确保关键字段存在,否则会触发 undefined 访问或静默失败。
- 设默认值:
if (!Object.hasOwn(config, 'timeout')) config.timeout = 5000; - 解构防护:
if (Object.hasOwn(user, 'id') && Object.hasOwn(user, 'name')) { const { id, name } = user; } - 避免因
user.id为undefined导致后续逻辑异常,也绕过user.id !== undefined对合法undefined值的误判
支持 Symbol 键的安全检测
当对象使用 Symbol 作为属性键(如私有状态、插件扩展标识)时,hasOwnProperty 虽支持,但调用方式易出错;Object.hasOwn 显式支持且类型更严谨。
- 正确用法:
const SYM_ID = Symbol('id'); Object.hasOwn(obj, SYM_ID); - 错误写法:
obj.hasOwnProperty('Symbol(id)')或obj.hasOwnProperty(SYM_ID.toString())—— 都查不到 - 适用于状态管理库内部字段校验、框架插件系统、元编程场景
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











