Object.create(null) 更快是因为其原型为 null,属性访问无需沿原型链查找,V8 可启用更优的隐藏类优化和内联缓存;普通对象需查找 Object.prototype,影响 IC 稳定性。

使用 Object.create(null) 创建对象可彻底切断原型链,避免属性访问时的继承查找,特别适合实现高频读写的哈希表(如缓存、映射索引、词频统计等)。它比普通对象({})少一层 Object.prototype 查找,在 V8 等引擎中能触发更优的隐藏类优化和内联缓存,提升属性读写性能。
为什么 Object.create(null) 更快?
普通对象(如 {a: 1})的原型链为:obj → Object.prototype → null。每次访问 obj.toString 或检查 obj.hasOwnProperty 时,引擎需沿链向上查找——即使你从不调用这些方法,JavaScript 引擎仍需预留原型链检查路径,影响内联缓存(IC)稳定性。
Object.create(null) 创建的对象原型为 null,即:obj → null。属性访问完全局限在自身属性表中,无继承干扰,V8 可将其识别为“字典模式”或启用更激进的快速属性访问优化。
构建纯净哈希表的实用写法
直接使用 Object.create(null) 作为底层存储,再封装常用操作:
- 用
const map = Object.create(null)初始化,不带任何默认方法 - 设置键值:无需
map.set(k, v),直接map[k] = v(支持字符串/数字/布尔作键,Symbol 需转字符串或改用 Map) - 安全取值:用
map[key] !== undefined判断存在性(不能用key in map,因无hasOwnProperty;也不建议用map[key] != null,会误判0、false、'') - 删除键:用
delete map[key],不依赖map.delete() - 遍历键:用
Object.keys(map)或for (const key in map)(因无原型属性,二者等效)
注意事项与边界处理
Object.create(null) 对象不继承任何方法,因此不能直接调用 .toString()、.hasOwnProperty()、.isPrototypeOf() 等。若需校验,应显式借用:
- 判断是否自有属性:
Object.prototype.hasOwnProperty.call(map, key) - 获取所有键:
Object.keys(map)安全可用(内部不依赖 this 的原型) - 避免意外覆盖保留字:如
map.constructor、map.__proto__在严格模式下是合法键名,但某些旧环境可能有兼容问题;建议统一用字符串键,或加前缀(如map['#'+key]) - JSON 序列化需注意:
JSON.stringify(map)正常工作,但反序列化后得到的是普通对象(原型恢复为Object.prototype),需再次Object.setPrototypeOf(jsonObj, null)或重新 create
对比 Map 与 Object.create(null) 的适用场景
两者都规避原型开销,但定位不同:
-
Object.create(null):轻量、零构造开销、支持任意字符串键(含空字符串、保留字)、可被
for...in遍历、内存占用略低;适合静态键集、高频单点读写、服务端路由表、CSS 类名映射等 -
Map:支持任意类型键(包括对象、函数、Symbol)、保持插入顺序、API 标准(
set/get/size/forEach)、弱引用支持(WeakMap);适合动态键、需迭代顺序、键不确定类型的场景
若仅需字符串键 + 极致性能 + 无额外依赖,Object.create(null) 是更直接的选择。现代引擎对其优化已非常成熟,无需顾虑兼容性(IE9+ 均支持)。


















