7.3. Разреженные массивы
Разреженным называется массив, индексы элементов которого не образуют непрерывную последовательность чисел, начиная с 0. Обычно свойство length массива определяет количество элементов в массиве. В разреженном массиве значение свойства length больше количества элементов. Разреженный массив можно создать с помощью конструктора Аггау() или путем присваивания значения элементу с индексом, большим, чем текущая длина массива.
а = new Array(5); // Нет элементов, но a.length имеет значение 5.
а = []; // Создаст пустой массив со значением length = 0.
а[1000] = 0; // Добавит один элемент, но установит длину равной 1001.
Далее будет показано, что разреженный массив можно также создать с помощью оператора delete.
Существенно разреженные массивы обычно более медленны и потребляют больше памяти, чем плотные массивы, а поиск элементов в таких массивах занимает примерно столько же времени, что и поиск обычных свойств объектов.
Обратите внимание, что литералы с пропущенными значениями (когда в определении подряд следуют запятые, например [1, ,3]) создают разреженные массивы, в которых пропущенные элементы просто не существуют:
var a1 = [,]; // Массив без элементов с длиной, равной 1
var а2 = [undefined]; // Массив с одним неопределенным элементом
О in а1 // => false: а1 не имеет элемента с индексом О
О in а2 // => true: а2 имеет элемент с индексом 0 и со значением undefined
Некоторые старые реализации (такие как Firefox 3) некорректно вставляли элементы со значением undefined на место пропущенных элементов. В этих реализациях литерал [1,,3] был эквивалентен литералу [1, undefined,3].
7.4. Длина массива
Любой массив имеет свойство length, и это свойство отличает массивы от обычных объектов JavaScript. Для плотных (т.е. неразреженных) массивов свойство length определяет количество элементов в массиве. Его значение на единицу больше самого большого индекса в массиве:
[].length // => 0: массив не имеет элементов
['а','Ь','с'].length // => 3: наибольший индекс равен 2, длина равна 3
Для разреженных массивов значение свойства length больше числа элементов, и все, что можно сказать в этом случае, - это то, что значение свойства length гарантированно будет превышать индекс любого элемента в массиве. Или, говоря иначе, массивы (разреженные или нет) никогда не будут содержать элемент, индекс которого будет больше или равен значению свойства length массива. Для поддержки этого свойства массивы проявляют две особенности поведения. Первая была описана выше: если присвоить значение элементу массива, индекс і которого больше или равен текущему значению свойства length, в свойство length записывается значение i+1.
Вторая особенность в поведении, обеспечивающем работу свойства length, заключается в том, что при присваивании свойству length неотрицательного целого числа n, меньшего, чем его текущее значение, все элементы массива с индексами, большими или равными значению n, удаляются из массива:
а = [1,2,3,4,5]; // Создать массив с пятью элементами.
a.length =3; // теперь массив а содержит элементы [1,2,3].
a.length = 0; // Удалит все элементы, а - пустой массив [].
a.length = 5; // Длина равна 5, но элементы отсутствуют, подобно Аггау(5)
В свойство length массива можно также записать значение больше, чем его текущее значение. В этом случае в массив не добавляются новые элементы, а просто создается разреженная область в конце массива.
В ECMAScript 5 свойство length массива можно сделать доступным только для чтения, с помощью Object.defineProperty() (раздел 6.7):
а = [1,2,3]; // Создать массив а с тремя элементами.
Object.defineProperty(a, ‘length", // Сделать свойство length
{writable: false}); // доступным только для чтения,
a.length =0; //а не изменится.
Аналогично, если сделать элемент массива ненастраиваемым, его нельзя будет удалить. Если элемент нельзя будет удалить, то и свойство length не может быть установлено в значение, меньшее или равное индексу ненастраиваемого элемента. (Смотрите раздел 6.7, а также описание методов Object.seal() и Object.freeze() в разделе 6.8.3.)