Кроме того, как уже было показано выше, имеется возможность удалять элементы в конце массива простым присваиванием нового значения свойству
<b>length</b>
. Массивы имеют метод
<b>рор()</b>
(противоположный методу
<b>push()</b>
), который уменьшает длину массива на 1 и возвращает значение удаленного элемента. Также имеется метод
<b>shift()</b>
(противоположный методу
<b>unshift()</b>
), который удаляет элемент в начале массива. В отличие от оператора
<b>delete</b>
, метод
<b>shift()</b>
сдвигает все элементы вниз на позицию ниже их текущих индексов. Методы
<b>рор()</b>
и
<b>shift()</b>
описываются в разделе 7.8 и в справочном разделе.
Наконец существует многоцелевой метод
<b>splice()</b>
, позволяющий вставлять, удалять и замещать элементы массивов. Он изменяет значение свойства
<b>length</b>
и сдвигает элементы массива с более низкими или высокими индексами по мере необходимости. Подробности приводятся в разделе 7.8.
7.6. Обход элементов массива
Наиболее часто для обхода элементов массива используется цикл
<b>for</b>
(раздел 5.5.3):
<b>var keys = Object.keys(o); // Получить массив имен свойств объекта о </b>
<b>var values = [] // Массив для сохранения значений свойств</b>
<b>for(var і = 0; і < keys.length; i++) { // Для каждого элемента в массиве </b>
<b> var key = keys[і]; // Получить имя свойства по индексу</b>
<b> values[i] = о[key]; // Сохранить значение в массиве values</b>
<b>}</b>
Во вложенных циклах и в других контекстах, когда скорость работы имеет критическое значение, иногда можно увидеть такой оптимизированный способ выполнения итераций по массиву, когда длина массива определяется только один раз, а не в каждой итерации:
<b>for(var і = 0, len = keys.length; і < len; i++) {</b>
<b> // тело цикла осталось без изменений</b>
<b>}</b>
В примерах выше предполагается, что выполняется обход плотного массива и все элементы содержат допустимые значения. В противном случае необходимо организовать проверку значений элементов массива перед их использованием. Если желательно исключить из обработки значения
<b>null, undefined</b>
и несуществующие элементы, проверку можно записать так:
<b>for(var і = 0; і < a.length; i++) { </b>
<b>if (!a[і]) continue; // Пропустить null, undefined и несуществ. элементы // тело цикла </b>
<b>} </b>
Если необходимо пропустить только значение undefined и несуществующие элементы, проверку можно записать так:
<b>for(var і = 0; і < a.length; i++) { </b>
<b>if (a[і] === undefined) continue; // Пропустить undefined + несуществ. эл. </b>
<b> // тело цикла </b>
<b>}</b>
Наконец, если необходимо пропустить только несуществующие элементы, а элементы со значением undefined обрабатывать как обычные элементы, проверку можно записать так:
<b>for(var і = 0; і < a.length; i++) {</b>
<b>if (!(i in a)) continue ; // Пропустить несуществующие элементы </b>
<b> // тело цикла</b>
<b>}</b>
Для обхода разреженных массивов можно также использовать цикл
<b>for/in</b>
(раздел 5.5.4). Этот цикл присваивает имена перечислимых свойств (включая индексы массива) переменной цикла. Отсутствующие индексы в итерациях не участвуют:
<b>for(var index in sparseArray) {</b>
<b> var value = sparseArray[index];</b>
<b> // Далее следуют операции с индексами и значениями</b>
<b>}</b>
Как отмечалось в разделе 6.5, цикл
<b>for/in</b>
может возвращать имена унаследованных свойств, такие как имена методов, добавленных в
<b>Array.prototype</b>
. По этой причине не следует использовать цикл
<b>for/in</b>
для обхода массивов, не предусмотрев дополнительной проверки для фильтрации нежелательных свойств. Для этого можно было бы использовать, например, такие проверки:
<b>for(var і in а) {</b>
<b> if (!a.hasOwnProperty(i)) continue; // Пропустить унаследованные свойства</b>
<b> // тело цикла</b>
<b>}</b>
<b>for(var і in а) {</b>
<b> // Пропустить і, если оно не является целым неотрицательным числом</b>
<b> if (String(Math.floor(Math.abs(Number(i)))) !== і) continue;</b>
<b>}</b>
Спецификация ECM AScript допускает возможность обхода свойств объекта в цикле
<b>for/in</b>
в любом порядке. Обычно реализации обеспечивают обход индексов массивов в порядке возрастания, но это не гарантируется. В частности, если массив имеет и свойства объекта, и элементы массива, имена свойств могут возвращаться в порядке их создания, а не в порядке возрастания числовых значений. Разные реализации по-разному обрабатывают эту ситуацию, поэтому, если для вашего алгоритма порядок выполнения итераций имеет значение, вместо цикла
<b>for/in</b>
лучше использовать обычный цикл
<b>for</b>
.