Object.hasOwn对null/undefined抛TypeError是设计使然,旨在严格校验参数类型、及早暴露数据问题;它不隐式转换,仅接受真实对象,配合obj != null && Object.hasOwn(obj, 'key')可安全使用。
Object.hasOwn 对 null 或 undefined 会直接抛出 TypeError,这不是缺陷,而是明确的设计意图:它只接受对象类型参数,不作隐式转换。
和传统 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 时,同样要求对象参数有效:
const sym = Symbol('id'); Object.hasOwn({[sym]: 1}, sym)
Object.hasOwn(null, sym) → 抛错,和字符串键一样Object.hasOwn(obj, 'Symbol(id)') → 不会匹配 Symbol 键,因为字符串和 Symbol 是不同类型