Object.create(null)创建无原型对象,彻底切断原型链,避免属性冲突和for...in污染,适用于哈希表、配置缓存等需绝对干净结构的场景。

用 Object.create(null) 可以创建一个完全不含原型链的“干净对象”,它既没有 toString、hasOwnProperty 等内置方法,也不继承自 Object.prototype。
为什么需要无原型的对象
普通对象(如 {} 或 new Object())默认继承自 Object.prototype,这会带来一些隐式行为和潜在冲突:
- 属性名可能意外覆盖原型方法(例如
obj.toString = 'xxx') - 使用
for...in遍历时会遍历到原型上的可枚举属性 - 某些工具或框架(如 Map 实现、配置合并逻辑)要求绝对“空白”结构,避免干扰
正确写法:Object.create(null)
这是最直接、标准的方式:
const cleanObj = Object.create(null); console.log(cleanObj.toString); // undefined console.log(cleanObj.hasOwnProperty); // undefined console.log(cleanObj.__proto__); // undefined(不是 null,但不可访问) console.log(Object.getPrototypeOf(cleanObj)); // null
注意:Object.create(null) 返回的对象其内部 [[Prototype]] 为 null,因此彻底切断了原型链。
与 {} 和 Object.defineProperty 的区别
对比常见写法:
-
{}:等价于Object.create(Object.prototype),有完整原型链 -
Object.create({}):创建的对象原型是空对象,但它本身仍继承自Object.prototype(因为{}就是Object.prototype的实例) -
Object.defineProperty({}, '__proto__', { value: null }):无效,__proto__是访问器属性,不能通过 defineProperty 改写为 null;且该操作不改变已有原型链
实用场景举例
适合用于需要高度可控键值行为的场合:
- 实现简易哈希表或字典:
const dict = Object.create(null); dict['some-key'] = 42; - 避免 hasOwnProperty 冲突:
if (dict.hasOwnProperty) {...}在普通对象中安全,但在用户可控 key 场景下,若 key 恰好是'hasOwnProperty'就会出错;用Object.create(null)后无需担心 - 构建 AST 节点、配置扁平化缓存、模块导出映射等底层结构
不复杂但容易忽略。记住:要真正“干净”,只认 Object.create(null)。

















