object.create(null) 创建无原型的纯粹字典对象,避免属性名冲突和继承干扰;普通对象 {} 继承 object.prototype 导致 tostring 等键访问异常、hasownproperty 失效等问题,适用缓存、配置收集等场景。

使用 Object.create(null) 是创建“纯粹字典对象”的最直接方式——它生成的对象没有 __proto__,也不继承 Object.prototype 上的任何方法(如 toString、hasOwnProperty、constructor 等),彻底避免了属性名冲突和意外继承行为。
为什么不用普通对象字面量 {}?
普通空对象 {} 实际等价于 Object.create(Object.prototype),因此自带一堆原型方法。这会导致:
- 当字典键恰好是
"toString"、"hasOwnProperty"等时,访问会命中原型而非自身属性; -
for...in遍历时可能受原型链影响(虽然这些方法通常不可枚举,但仍有潜在风险); - 用
obj.hasOwnProperty(key)判断存在性会失效(因为obj自身没有该方法)。
如何正确创建并安全使用 Object.create(null) 对象
创建后需注意:它真的“一无所有”,连基础方法都没有,所以操作要更谨慎:
- 赋值和读取属性和普通对象一样:
dict.foo = 'bar'; console.log(dict.foo); - 检查属性是否存在,不能用
dict.hasOwnProperty(key)(会报错),改用Object.prototype.hasOwnProperty.call(dict, key)或更简洁的key in dict; - 获取所有键可用
Object.keys(dict)(它内部不依赖对象自身的hasOwnProperty); - 遍历推荐用
for (const key of Object.keys(dict))或Object.entries(dict),避免for...in(尽管此时没原型干扰,但习惯上更清晰)。
典型适用场景
这种对象特别适合做纯数据映射,例如:
- 缓存对象(key 是字符串,value 是任意值,绝不希望被原型方法污染);
- 配置项合并工具中的临时收集器;
- 实现自定义 Map-like 结构(比如带默认值的字典);
- 处理用户输入的字段名(如表单字段、API 响应 key),防止恶意覆盖内置方法名。
一个小提醒:别忘了类型判断
由于它不是 instanceof Object(Object.create(null) instanceof Object === false),若代码中有类似 typeof obj === 'object' && obj !== null 的判断,仍能通过;但依赖 obj.constructor === Object 或 obj.toString() 的逻辑会出错。必要时可加一层封装或显式标记:
const dict = Object.create(null); dict.__isDict = true; // 手动标记,仅当需要区分时










