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