Object.create(null) 创建的对象无原型、无继承方法,是真正“空”的键值容器;适用于哈希表、防污染配置等场景,但不可直接调用 hasOwnProperty 等方法,需用 Object.prototype 方法显式调用。

用 Object.create(null) 创建的对象确实没有原型(即 __proto__ 为 null,Object.getPrototypeOf(obj) === null),它不继承任何内置方法(如 toString、hasOwnProperty、constructor 等),是一个真正“空”的键值容器——常用于哈希表、配置映射、避免原型污染等场景。
为什么不用 {}?
普通对象字面量 {} 的原型是 Object.prototype,因此自带一堆方法:
-
obj.toString()可用(可能意外触发或被覆盖) -
'toString' in obj返回true(即使没显式定义) - 若 key 恰好是
"constructor"或"hasOwnProperty",可能和原型链上的同名方法冲突 - 容易受原型污染攻击(比如恶意设置
Object.prototype.pollute = ...)
怎么创建并安全使用?
直接调用即可:
const map = Object.create(null); map.id = 123; map.name = 'Alice'; console.log(map.id); // 123 console.log(map.toString); // undefined(不是 Function) console.log(Object.getPrototypeOf(map)); // null
注意:由于没有原型,不能直接调用 hasOwnProperty 等方法。需改用全局 Object.prototype 上的方法:
- 判断属性是否存在:
Object.prototype.hasOwnProperty.call(map, 'id') - 获取所有自有键:
Object.keys(map)(这个仍可用,因为它是静态方法) - 遍历:
for (const key in map)不会遍历原型属性(本来就没有),但建议优先用Object.keys()或Reflect.ownKeys()
常见适用场景
-
字符串映射表:如
const cache = Object.create(null); cache['/api/user'] = userData; -
事件监听器注册表:避免 key 冲突(如
"on"、"once"是常用方法名) -
防污染的配置对象:接收外部 JSON 或用户输入时,用
Object.create(null)作为基础容器更安全 -
实现 Map-like 结构(仅限字符串 key):比原生
Map轻量,但无迭代顺序保证、不支持非字符串 key
小提醒
它不是万能替代品。如果需要继承行为、方法、或与大量已有 API 兼容(比如期望对象有 toString),就别用它。另外,JSON.stringify(map) 是可以的(输出 {}),但 JSON.parse() 得到的仍是普通对象(原型不为空),需手动转换。


















