V8 内部如何表示对象?

How are objects represented internally in V8?

我一直认为 javascript 中的对象是简单的键值对,即哈希表,但在阅读 this 文章后我感到困惑。

作者特意说:

when you use an object as if it was a hash table, it will be turned into a hash table.

所以,之前是什么鬼?特别是整个段落让我感到困惑。有人可以解释一下吗?

根据 this answer,在 V8 中对象可以有两种模式——字典模式快速模式

对象最初处于快速模式,其中 属性 访问不需要散列映射(不需要计算)。它像 C 中的结构一样存储对象。只有在您开始使用 "object as if it was a hash table, it will be turned into a hash table" 字典模式时才会这样。一旦发生这种情况,您将获得在幕后使用哈希映射进行 属性 访问的性能损失。

例如:

// running node with `--allow-natives-syntax` flag

var obj = { a: true, b: false };
%HasFastProperties(obj); // true (Fast mode)
delete obj.a;
%HasFastProperties(obj); // false (Dictionary mode)

或者:

var obj = { a: true, b: false };
%HasFastProperties(obj); // true (Fast mode)
// add lots of properties
for (var i = 0; i < 100; i++) {
    obj["prop" + i] = i;
}
%HasFastProperties(obj); // false (Dictionary mode)

这样做时进入字典模式的原因是性能优化。在字典模式下 add/remove 属性比快速模式更快,因此 V8 引擎在检测到此行为时针对更改结构而不是 属性 访问进行了优化 (Read more here)。