Действительно ли массивы javascript реализованы как массивы? - PullRequest
19 голосов
/ 10 февраля 2012

Разница между javascript Array и Object не очень большая. На самом деле кажется, что Array в основном добавляет поле length, поэтому вы можете использовать как Array s, так и Object s в качестве числовых массивов:

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. Array - это то же самое, что и Object, и все объекты получают эвристику, чтобы увидеть, имеет ли смысл использовать массив.
  4. Что-то безумно сложное, о чем я не думал.

Действительно, было бы проще, если бы существовал правильный тип массива ( кашель Массивы, набранные WebGL кашель ).

Ответы [ 2 ]

13 голосов
/ 18 февраля 2012

В SpiderMonkey массивы реализованы в основном как C-массивы jsvals. Они называются «плотными массивами». Однако, если вы начнете делать с ними не подобные массиву вещи - например, относиться к ним как к объектам - их реализация изменится на нечто, очень похожее на объекты.

Мораль истории: когда вы хотите массив, используйте массив. Когда вы хотите объект, используйте объект.

О, jsval - это разновидность типа variadic, которая может представлять любое возможное значение JavaScript в 64-битном типе C.

7 голосов
/ 11 июля 2012

В V8 и Carakan (и предположительно Chakra) все (не хостовые) объекты (как массивы, так и не имеющие) со свойствами, имена которых являются индексами массива (как определено в ES5), сохраняются как плотный массив (массив C, содержащий некоторую оболочку значения) или разреженный массив (который реализован в виде двоичного дерева поиска).

Унифицированное представление объекта проявляется в том, что оно влияет на порядок перечисления: с объектом SpiderMonkey и SquirrelFish оба дают все свойства в порядке вставки; и с массивом, они вообще (есть особые случаи в SM хотя бы!) сначала индексируют массив, затем все остальные свойства в порядке вставки. V8, Carakan и Chakra всегда сначала дают индексы массива, а затем все остальные свойства в порядке вставки, независимо от типа объекта.

...