深入javascript引擎(3)

在 JavaScript 语言红,多个对象具有相同的键值属性的。我们可以认为这些对象都具有相同的结构,也就是形状,其他语言例如 c++ 用 structure 来表示定义的结构。

8207483-84f35d9163928c35.jpg

定义一个没有任何属性的对象,这样会对象指定一个空 shape。现在为 empty 对象添加了一个属性,此时会发生什么?在 JavaScript 引擎中,shapes 的表现形式被称作 transition 链。 

如果对象添加值为 5 的属性 “x”, JavaScript 引擎转向一个具有属性 “x” 的 Shape,并向 JSObject 的第一个偏移量为 0 处添加了一个值 5。

8207483-1647f3d0d4a0c8bd.jpg

继续给对象添加了一个属性 'y',引擎便转向另一个包含 'x' 和 'y' 的 Shape,并将值 6 附加到 JSObject(位于偏移量 1 处)。

8207483-5c40c215857d586b.jpg

 接下来一个语句添加了一个属性 'y',引擎便转向另一个包含 'x' 和 'y' 的 Shape,并将值 6 附加到 JSObject(位于偏移量 1 处)。

我们甚至不需要为每个 Shape 存储完整的属性表。相反,每个 Shape 只需要知道它引入的新属性。 例如在此例中,我们不必在最后一个 Shape 中存储关于 'x' 的信息,因为它可以在更早的链上被找到。要做到这一点,每一个 Shape 都会与其之前的 Shape 相连:

8207483-0edd071776a22659.jpg

并不需要为每个 Shape 来保存完整的属性表。每个 Shape 只需要知道引入的新属性。 如图,我们不必在最后一个 Shape 中存储关于 'x' 的信息,因为它可以在更早的链上被找到。要做到这一点,每一个 Shape 都会与其之前的 Shape 相连:

8207483-4d8e437683eebfe7.jpg

如果你在 JavaScript 代码中写到了 o.x,则 JavaScript 引擎会沿着 transition 链去查找属性 “x”,直到找到引入属性 “x”的 Shape。

但是,如果不能只创建一个 transition 链呢?例如,如果你有两个空对象,并且你为每个对象都添加了一个不同的属性?

8207483-9e889951699af6df.jpg

现在创建一个空对象 a,然后为添加一个属性 'x'。 以及两个 Shapes:空 Shape 和仅包含属性 x的 Shape。

再定义一个空对象 b 开始的,随后为此对象添加了一个不同的属性 'y'。我们最终形成两个 shape 链,总共是三个 shape。

现在我们来想一个问题,每一次创建对象都否意味着我们总是需要从空 shape 开始呢?其实并不是。引擎对已包含属性的对象字面量会应用一些优化。比方说,我们要么从空对象字面量开始添加 x 属性,要么有一个已经包含属性 x 的对象字面量:

8207483-feb3df6b06d639b1.jpg

在第一个例子中,我们从空 shape 开始,然后转向包含 x 的 shape,这正如我们我们之前所见。


8207483-bcadc50c69db5402.jpg

在 objectb一例中,直接生成具有属性 x 的对象是有意义的,而不是从空对象开始然后进行 transition 连接。

8207483-4cd8d765f2a7c084.jpg
8207483-96507be22ecb031d.jpg

猜你喜欢

转载自blog.csdn.net/weixin_34101229/article/details/86797439