20

ArrayJavaScript和JavaScript 之间的区别Object并不是很大。实际上它似乎Array主要是添加length字段,因此您可以将Arrays 和Objects 用作数字数组:

var ar = new Array();
ar[0] = "foo";
ar["bar"] = "foo";

var ob = new Object();
ob[0] = "foo";
ob["bar"] = "foo";

assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.

所以我的问题是,在流行的 JavaScript 引擎V8、JavaScriptCore、SpiderMonkey等)中,这是如何处理的?显然,我们不希望我们的数组实际存储为带有键值的哈希映射!我们如何合理地确定我们的数据存储为实际数组?

据我所知,引擎可以采取以下几种方法:

  1. ArrayObject实现方式与- 作为具有字符串键的关联数组完全相同。
  2. Array是一种特殊情况,有一个类似std::vector- 的数组支持数字键,如果你这样做,一些密度启发式可以防止疯狂的内存使用ar[100000000] = 0;
  3. Array与 相同Object,并且所有对象都会得到启发,以查看使用数组是否更有意义。
  4. 我没有想到的疯狂复杂的事情。

如果有适当的数组类型(咳嗽 WebGL类型数组咳嗽),这确实会更简单。

4

2 回答 2

15

在 SpiderMonkey 中,数组基本上是作为 jsval 的 C 数组实现的。这些被称为“密集阵列”。然而,如果你开始对它们做类似非数组的事情——比如把它们当作对象对待——它们的实现就会变成非常类似于对象的东西。

故事的寓意:当你想要一个数组时,就使用一个数组。当你想要一个对象时,使用一个对象。

哦,jsval 是一种可变参数类型,它可以表示 64 位 C 类型中的任何可能的 JavaScript 值。

于 2012-02-18T02:42:24.220 回答
7

在 V8 和 Carakan(可能还有 Chakra)中,所有(非主机)对象(包括数组和非主机)具有名称为数组索引(如 ES5 中定义)的属性都存储为密集数组(包含一些值包装器的 C 数组)或稀疏数组(实现为二叉搜索树)。

统一的对象表示表明它会影响枚举顺序:对于一个对象,SpiderMonkey 和 SquirrelFish 都以插入顺序给出所有属性;对于数组,它们通常(至少在 SM 中有特殊情况!)数组索引首先是插入顺序中的所有其他属性。V8、Carakan 和 Chakra 总是先给出数组索引,然后按插入顺序给出所有其他属性,而不管对象类型如何。

于 2012-07-11T13:31:38.933 回答