Если я задаю только высокий индекс в массиве, разве это потеря памяти?

В Javascript, если я что-то вроде

var alpha = [];
alpha[1000000] = 2;

как-то эта потеря памяти? Я помню, что читал что-то о массивах Javascript, которые все еще устанавливают значения для неопределенных индексов (возможно, их устанавливает в undefined?), Но я думаю, что это могло иметь какое-то отношение к удалению. Я не могу вспомнить.

Ответы

Ответ 1

Смотрите эту тему: are-javascript-arrays-sparse

В большинстве реализаций Javascript (возможно, все современные) массивы разрежены. Это означает, что нет, он не собирается выделять память до максимального индекса.

Если это что-то вроде реализации Lua, на самом деле есть внутренний массив и словарь. Плотно заполненные части из начального индекса будут храниться в массиве, разреженные части в словаре.

Ответ 2

Это старый миф. Другие индексы в массиве не будут назначены.

Когда вы назначаете имя свойства, которое является "индексом массива" (например, alpha[10] = 'foo', имя, которое представляет 32-битное целое без знака), и оно больше текущего значения свойства length для Array, произойдут две вещи:

  • Свойство "index named" будет создано на объекте.
  • length будет увеличиваться так, чтобы index + 1.

Доказательство концепции:

var alpha = [];
alpha[10] = 2;
alpha.hasOwnProperty(0);  // false, the property doesn't exist
alpha.hasOwnProperty(9);  // false
alpha.hasOwnProperty(10); // true, the property exist
alpha.length;             // 11

Как вы можете видеть, метод hasOwnProperty возвращает false, когда мы проверяем наличие 0 или 9, потому что они физически не существуют на объекте, тогда как он возвращает true для 10, свойство было создано.

Это заблуждение, вероятно, происходит из популярных консолей JS, таких как Firebug, потому что, когда они обнаруживают, что напечатанный объект подобен массиву, они просто создают цикл, отображая каждый из значений индекса от 0 до length - 1.

Например, Firebug обнаруживает объекты, подобные массиву, просто глядя, есть ли у них свойство length, его значение представляет собой неподписанное 32-битное целое число (менее 2 ^ 32 - 1) и если они имеют splice свойство, которое является функцией:

console.log({length:3, splice:function(){}});
// Firebug will log: `[undefined, undefined, undefined]`

В приведенном выше случае Firebug будет внутренне создавать последовательный цикл, чтобы отображать каждое из значений свойств, но ни один из индексов действительно не существует, а показ [undefined, undefined, undefined] даст вам ложное ощущение того, что эти свойства существуют, или что они были "выделены", но это не так...

Это было так, что с тех пор он даже указывал на спецификацию ECMAScript 1st Edition (с 1997 года), вы не должны беспокоиться о различиях в реализации.

Ответ 3

Примерно год назад я провел некоторое тестирование на то, как браузеры обрабатывают массивы (обязательная самоподдерживающая ссылка на мой пост в блоге). Мое тестирование был направлен скорее на производительность ЦП, чем на потребление памяти, что намного сложнее измерить. Суть в том, что каждый браузер, который я тестировал, как представляется, рассматривал разреженные массивы как хеш-таблицы. То есть, если вы не инициализировали массив из get-go, поместив значения в последовательные индексы (начиная с 0), массив будет реализован таким образом, который, казалось бы, оптимизировался для пространства.

Таким образом, пока нет гарантии, я не думаю, что установка array[100000] займет больше места, чем установка array[1] - если вы также не установите все индексы, ведущие к этим.

Ответ 4

Я так не думаю, потому что javascript рассматривает массивы вроде как словари, но с целыми ключами.

alpha [1000000] = альфа [ "1000000" ]

Ответ 5

Я действительно не знаю javascript, но это было бы довольно странное поведение, если бы он не выделял пространство для всего массива. Почему вы думаете, что это не займет место? Вы просите огромный массив. Если это не даст вам это, это будет конкретная оптимизация.

Это, очевидно, игнорирует оптимизацию ОС, такую ​​как избыточность памяти и другие особенности ядра и реализации.