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

发布于 2025-01-04 15:19:27 字数 1237 浏览 1 评论 0原文

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. 一些我没有想到的极其复杂的事情。

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

The difference between a JavaScript Array, and Object is not very big. In fact it seems Array mainly adds the length field, so you can use both Arrays and Objects as numeric arrays:

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.

So my questions is, in popular JavaScript engines (V8, JavaScriptCore, SpiderMonkey, etc.), how is this handled? Obviously we do not want our arrays to be actually stored as hash maps with key values! How can we be reasonably sure our data is stored as an actual array?

As far as I can see there are a few approaches engines could take:

  1. Array is implemented exactly the same way as Object - as an associative array with string keys.
  2. Array is a special case, with a std::vector-like array backing the numeric keys, and some density heuristic to prevent insane memory use if you do ar[100000000] = 0;
  3. Array is the same as Object, and all objects get a heuristic to see if using an array would make more sense.
  4. Something insanely complicated that I haven't thought of.

Really this would be simpler if there were a proper array type (cough WebGL typed arrays cough).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

A君 2025-01-11 15:19:27

在 SpiderMonkey 中,数组基本上被实现为 jsval 的 C 数组。这些被称为“密集阵列”。但是,如果您开始对它们执行非数组式的操作(例如将它们视为对象),它们的实现将更改为非常类似于对象的操作。

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

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

In SpiderMonkey, arrays are implemented basically as C arrays of jsvals. These are referred to as "dense arrays". However, if you start doing un-array-like things to them -- like treating them like objects -- their implementation is changed to something which very much resembles objects.

Moral of the story: when you want an array, use an array. When you want an object, use an object.

Oh, a jsval is a sort of variadic type which can represent any possible JavaScript value in a 64 bit C type.

那支青花 2025-01-11 15:19:27

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

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

In V8 and Carakan (and presumably Chakra), all (non-host) objects (both those that are arrays and those that aren't) with properties whose names are array indexes (as defined in ES5) are stored as either a dense array (a C array containing some value wrapper) or a sparse array (which is implemented as a binary search tree).

The unified object representation shows through in that it affects enumeration order: with an object, SpiderMonkey and SquirrelFish both give all properties in insertion order; and with an array, they in general (there are special cases in SM at least!) array indexes first then all other properties in insertion order. V8, Carakan, and Chakra always give array indexes first then all other properties in insertion order, regardless of object type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文