object.hasown 是校验对象自身属性存在的安全基准写法,专查自有属性、不触原型链、不依赖对象方法、不混淆值与存在性,适用于不可信数据、必填校验、解构兜底、for...in 过滤及 symbol 键检测。

用 Object.hasOwn 做属性存在性校验,核心是明确“只查对象自身定义的属性”,不碰原型链、不依赖对象方法、不混淆值与存在性。它不是语法糖,而是现代 JS 中安全校验的基准写法。
什么时候必须用 Object.hasOwn
以下场景若仍用 obj.hasOwnProperty('key') 或 'key' in obj,就容易出错或被绕过:
- 处理用户输入、API 返回、JSON 解析结果等不可信数据(可能含
hasOwnProperty: null或Object.create(null)) - 配置项必填校验,比如
if (!Object.hasOwn(config, 'baseUrl')) throw new Error('baseUrl required') - 解构前兜底,避免
const { id } = data因data缺失id而静默失败 - 遍历
for...in时过滤掉原型属性(如toString、constructor),只操作自有键 - 检测 Symbol 键,例如
Object.hasOwn(obj, Symbol.for('token')),兼容性比旧方法更稳
怎么写才规范
写法要统一、语义清晰、兼顾类型安全:
- 直接调用:
Object.hasOwn(obj, 'key')—— 不加call、不绑定、不封装函数 - 前置类型防护:如果
obj可能为null或undefined,先做判断:obj != null && typeof obj === 'object' && Object.hasOwn(obj, 'key') - 禁止混用:不用
obj.hasOwn(不存在)、不用obj.hasOwnProperty(风险高)、不用Reflect.has(那是查原型链的) - 批量检查时别重复调用:若需查多个键,可先缓存
Object.keys(obj)或Object.getOwnPropertyNames(obj),再用.includes(),但仅限高频批量场景
兼容旧环境的稳妥降级
目标环境不支持 Object.hasOwn(如 Node.js 14 或 IE)时,不写 polyfill 也能安全降级:
- 用
Object.prototype.hasOwnProperty.call(obj, 'key')替代 —— 它绕过对象自身查找路径,100% 可靠 - 不要写
obj.hasOwnProperty('key'),哪怕加了obj &&保护也不够 —— 重写方法或Object.create(null)仍会失效 - 构建工具中可设
target: 'ES2022'为底线;若必须兼容更低版本,统一注入轻量 fallback,而非放任不安全调用
哪些写法要立刻停用
这些看似省事的写法,本质是逻辑错位,长期维护成本高:
-
obj.key !== undefined:属性存在但值为undefined就误判;obj为null直接报错 -
Object.keys(obj).includes('key'):漏掉不可枚举属性(如toJSON),每次调用都生成新数组,O(n) 开销 -
'key' in obj用于自有属性判断:它查整个原型链,Object.prototype.key = true就会导致所有空对象都“有 key” -
if (obj.key):把0、false、''全当“不存在”,且可能触发 getter 副作用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











