JavaScript 中 Object.hasOwn 处理 null 或 undefined 对象时的安全性

作者:袖梨 2026-07-04
Object.hasOwn对null/undefined抛TypeError是设计使然,旨在严格校验参数类型、及早暴露数据问题;它不隐式转换,仅接受真实对象,配合obj != null && Object.hasOwn(obj, 'key')可安全使用。

Object.hasOwn 对 nullundefined 会直接抛出 TypeError,这不是缺陷,而是明确的设计意图:它只接受对象类型参数,不作隐式转换。

为什么它不自动处理 null/undefined?

和传统 obj.hasOwnProperty() 不同,Object.hasOwn 是静态方法,不依赖目标对象的原型链或内部结构。但它也更严格——只对真实对象负责。这种“失败即报错”的策略,反而帮你及早暴露数据来源问题,而不是让逻辑在深层静默出错。

  • Object.hasOwn(null, 'key') → 抛 TypeError: Cannot convert undefined or null to object
  • Object.hasOwn(undefined, 'key') → 同样抛错
  • Object.hasOwn({}, 'key')Object.hasOwn(new Date(), 'getTime') → 正常工作

安全写法:先判空再检测

实际开发中,对象可能来自 API 响应、用户输入或可选参数,必须主动防护:

  • ✅ 推荐:用 obj != null && typeof obj === 'object' 做前置判断
  • ✅ 简洁组合:obj != null && Object.hasOwn(obj, 'prop')
  • ❌ 避免:Object.hasOwn(obj || {}, 'prop') —— 若 obj 是字符串或数字,obj || {} 会掩盖类型错误,且字符串/数字对象可能有意外自有属性(如 'abc'.length

对比其他方式的容错差异

这种“严格”恰恰是它的优势:

立即学习“Java免费学习笔记(深入)”;

  • 'prop' in obj:对 null/undefined 返回 false,看似安全,但会查原型链,可能误判继承属性
  • obj?.prop !== undefined:能防崩溃,但无法区分“属性不存在”和“属性存在但值为 undefined
  • Object.prototype.hasOwnProperty.call(obj, 'prop'):对 null/undefined 同样抛错,行为一致,但写法冗长且仍依赖 Object.prototype 未被篡改

Symbol 键也要注意类型

传入 Symbol 时,同样要求对象参数有效:

  • const sym = Symbol('id'); Object.hasOwn({[sym]: 1}, sym)
  • Object.hasOwn(null, sym) → 抛错,和字符串键一样
  • Object.hasOwn(obj, 'Symbol(id)') → 不会匹配 Symbol 键,因为字符串和 Symbol 是不同类型

相关文章

精彩推荐