在 JavaScript 语言红,多个对象具有相同的键值属性的。我们可以认为这些对象都具有相同的结构,也就是形状,其他语言例如 c++ 用 structure 来表示定义的结构。
![](https://img.haomeiwen.com/i8207483/84f35d9163928c35.jpg)
定义一个没有任何属性的对象,这样会对象指定一个空 shape。现在为 empty 对象添加了一个属性,此时会发生什么?在 JavaScript 引擎中,shapes 的表现形式被称作 transition 链。
如果对象添加值为 5 的属性 “x”, JavaScript 引擎转向一个具有属性 “x” 的 Shape,并向 JSObject 的第一个偏移量为 0 处添加了一个值 5。
![](https://img.haomeiwen.com/i8207483/1647f3d0d4a0c8bd.jpg)
继续给对象添加了一个属性 'y',引擎便转向另一个包含 'x' 和 'y' 的 Shape,并将值 6 附加到 JSObject(位于偏移量 1 处)。
![](https://img.haomeiwen.com/i8207483/5c40c215857d586b.jpg)
接下来一个语句添加了一个属性 'y',引擎便转向另一个包含 'x' 和 'y' 的 Shape,并将值 6 附加到 JSObject(位于偏移量 1 处)。
我们甚至不需要为每个 Shape 存储完整的属性表。相反,每个 Shape 只需要知道它引入的新属性。 例如在此例中,我们不必在最后一个 Shape 中存储关于 'x' 的信息,因为它可以在更早的链上被找到。要做到这一点,每一个 Shape 都会与其之前的 Shape 相连:
![](https://img.haomeiwen.com/i8207483/0edd071776a22659.jpg)
并不需要为每个 Shape 来保存完整的属性表。每个 Shape 只需要知道引入的新属性。 如图,我们不必在最后一个 Shape 中存储关于 'x' 的信息,因为它可以在更早的链上被找到。要做到这一点,每一个 Shape 都会与其之前的 Shape 相连:
![](https://img.haomeiwen.com/i8207483/4d8e437683eebfe7.jpg)
如果你在 JavaScript 代码中写到了 o.x,则 JavaScript 引擎会沿着 transition 链去查找属性 “x”,直到找到引入属性 “x”的 Shape。
但是,如果不能只创建一个 transition 链呢?例如,如果你有两个空对象,并且你为每个对象都添加了一个不同的属性?
![](https://img.haomeiwen.com/i8207483/9e889951699af6df.jpg)
现在创建一个空对象 a,然后为添加一个属性 'x'。 以及两个 Shapes:空 Shape 和仅包含属性 x的 Shape。
再定义一个空对象 b 开始的,随后为此对象添加了一个不同的属性 'y'。我们最终形成两个 shape 链,总共是三个 shape。
现在我们来想一个问题,每一次创建对象都否意味着我们总是需要从空 shape 开始呢?其实并不是。引擎对已包含属性的对象字面量会应用一些优化。比方说,我们要么从空对象字面量开始添加 x 属性,要么有一个已经包含属性 x 的对象字面量:
![](https://img.haomeiwen.com/i8207483/feb3df6b06d639b1.jpg)
在第一个例子中,我们从空 shape 开始,然后转向包含 x 的 shape,这正如我们我们之前所见。
![](https://img.haomeiwen.com/i8207483/bcadc50c69db5402.jpg)
在 objectb一例中,直接生成具有属性 x 的对象是有意义的,而不是从空对象开始然后进行 transition 连接。
![](https://img.haomeiwen.com/i8207483/4cd8d765f2a7c084.jpg)
![](https://img.haomeiwen.com/i8207483/96507be22ecb031d.jpg)
网友评论