JavaScript V8引擎中将值设为null为何比设为undefined速度更快?
V8引擎下Object属性赋值null/undefined与delete操作的性能差异原因
你测试时每次新建对象/Map保证初始状态一致的操作,排除了对象隐藏类初始状态不同的干扰,测试数据具备参考性,具体性能差异的原因可以分为几类:
- delete操作慢的核心原因
V8 对普通Object的默认优化是基于隐藏类(也叫Shape,区别于JS内置的Map结构)实现的:同一个结构的对象会共享同一个隐藏类,属性访问可以通过固定偏移量直接寻址,速度接近C++结构体。当你使用delete删除属性时,会直接破坏当前对象的隐藏类结构,导致对象从快速模式降级为字典模式,后续所有属性操作都需要走哈希表查询,开销会提升一个数量级。 - 赋值null比赋值undefined快的原因
- 类型层面:null是V8内部预先定义的标准单例原始值,类型标记固定,赋值时只需要修改属性槽的指针指向,不需要额外校验。
- 语义层面:给属性赋值null时,V8会判定该属性依然处于激活状态,对象的隐藏类不会发生任何变化,对应的内联缓存(Inline Cache)可以完全命中,性能最优。而给属性赋值undefined时,V8内部会触发额外的属性语义校验:比如需要标记该属性为“逻辑不存在”状态,部分场景下还会检查该属性是否可配置、是否有绑定访问器,同时该属性的内联缓存会被标记为失效,无法享受后续的优化收益。
- 存在逻辑漏洞的基准测试出现极端差距的原因
该测试中重复给已经是null的属性赋值null的操作,会被V8的JIT编译器判定为无副作用的冗余操作,直接在编译阶段优化掉,相当于跑空循环,所以操作速度可以达到数百万次/秒。而重复给属性赋值undefined的操作,因为undefined赋值存在额外的语义检查逻辑,没有被编译器判定为可消除的冗余操作,需要实际执行赋值流程,所以两者会出现上千倍的性能差距,这个差距完全是编译器优化导致的,没有实际业务参考价值。 - 补充说明Map的性能差异
JS内置的Map本身就是基于哈希表实现的,没有隐藏类的优化机制,所以赋值null、undefined的性能差异远小于普通Object,但依然是null稍快,核心原因也是null的类型校验逻辑比undefined更简单。
内容的提问来源于stack exchange,提问作者ScriptType
相关产品推荐
相关产品推荐

