javascript Arrays实际上是作为数组实现的吗?

时间:2012-02-10 19:42:22

标签: javascript arrays performance v8 spidermonkey

javascript ArrayObject之间的差异不是很大。事实上似乎Array主要添加了length字段,因此您可以同时使用ArrayObject作为数字数组:

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. Array的实现方式与Object完全相同 - 作为带字符串键的关联数组。
  2. Array是一个特例,有一个支持数字键的std::vector - 类数组,还有一些密度启发式算法可以防止疯狂的内存使用ar[100000000] = 0;
  3. ArrayObject相同,并且所有对象都会获得启发式功能,以查看使用数组是否更有意义。
  4. 我没想过的东西非常复杂。
  5. 如果有适当的数组类型( cough WebGL类型数组 cough ),这会更简单。

2 个答案:

答案 0 :(得分:13)

在SpiderMonkey中,数组基本上是作为jsvals的C数组实现的。这些被称为“密集阵列”。但是,如果你开始对它们做类似非数组的事情 - 比如像对象一样对待它们 - 它们的实现会变成非常类似于对象的东西。

故事的道德:当你想要一个数组时,使用一个数组。如果需要对象,请使用对象。

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

答案 1 :(得分:7)

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

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