谈谈隐藏类

4views

先来看一个问题,以下哪段代码执行效率更高:

const obj1 = {
    a: 1
}
const obj2 = {
    a: 1
}
const obj3 = {
    a: 1
}
const obj1 = {
    a: 1
}
const obj2 = {
    b: 1
}
const obj3 = {
    c: 1
}

答案是:左边效率更高,因为重用了隐藏类(Hidden Class)

关于隐藏类,可以参考这篇文章

我们来试一试:

console.time("a")
for (let i = 0; i < 1000000; i++) {
  const obj = {}
  obj["a"] = i
}
console.timeEnd("a")

console.time("b")
for (let i = 0; i < 1000000; i++) {
  const obj = {}
  obj[`${i}`] = i
}
console.timeEnd("b")

最终打印结果:

a: 2.129ms
b: 210.115ms

原因分析:

  1. V8 是一个 C++ 实现的 JS 解析引擎,内部利用隐藏类(Hidden Class)方式来存放 JS 对象。
  2. 隐藏类特性:多个属性顺序一致的JS对象,会重用一个隐藏类,减少 new Class 的开销。

因此,得出优化建议:

  1. 在构造函数中初始化所有属性,尽量避免“添加动态属性”的场景。
  2. 始终按照同样属性顺序构建对象,使得隐藏类可以重用。
  3. 不要加载未初始化或已经删除的属性。