object.create(null)创建的对象因原型为null而缺失hasownproperty等方法,调用会报typeerror;可用object.hasown(obj, key)或object.prototype.hasownproperty.call(obj, key)安全检测自有属性。

会直接报错,因为这类对象没有原型链,自然也找不到 hasOwnProperty 方法。
为什么调用就失败
普通对象(比如 {} 或 Object.create(Object.prototype))的原型是 Object.prototype,所以能访问到 hasOwnProperty。而 Object.create(null) 创建的对象,其 __proto__ 是 null,不继承任何方法——toString、valueOf、hasOwnProperty 全都不存在。
一旦写 obj.hasOwnProperty('key'),运行时就会抛出:
TypeError: obj.hasOwnProperty is not a function
哪些操作也会出问题
-
obj.toString()→ 报错 -
obj.valueOf()→ 报错 -
obj.isPrototypeOf({})→ 报错 - 任何依赖
Object.prototype上方法的操作,只要没做兜底,都会中断
安全检测自有属性的替代方案
别硬补方法,改用语言级或标准库提供的健壮方式:
-
Object.hasOwn(obj, key):ES2022 引入,专为解决此问题设计。不查原型、不依赖对象自身方法,兼容Object.create(null),且不受重写影响 -
Object.prototype.hasOwnProperty.call(obj, key):通用回退方案,绕过实例查找,直接借用原型方法,所有环境都可用 -
key in obj:对Object.create(null)安全(因原型为null,in不会向上查找),但注意它查的是“自身 + 原型链”,而此时原型链为空,效果等同于检查自有属性
什么时候该选 Object.create(null)
不是为了“看起来干净”,而是有明确需求:
- 做哈希表/事件监听器存储,键名不可控(比如可能叫
toString、constructor) - JSON Schema 校验上下文、AST 节点元数据容器,需避免原型方法干扰
- 写底层工具函数(如
isPlainObject),必须排除原型污染风险
若只是存配置、不需要防御原型污染,{} 更自然;若需任意类型 key 或迭代顺序保证,Map 更合适。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











