Перейти к содержанию

Итерации по массивам и свойства

Несмотря на то, что массивы в JavaScript являются объектами, нет достаточных оснований для использования цикла for in для итерации по элементам массива. Фактически, существует несколько весомых причин против использования for in в массивах.

Замечание: Массивы в JavaScript не являются ассоциативными массивами. Для связывания ключей и значений в JavaScript есть только объекты. И при том, что ассоциативные массивы сохраняют заданный порядок, объекты не делают этого.

Во время выполнения for in циклически перебираются все свойства объекта, находящиеся в цепочке прототипов. Единственный способ исключить ненужные свойства — использовать hasOwnProperty, а это в 20 раз медленнее обычного цикла for.

Итерирование

Для достижения лучшей производительности при итерации по массивам, лучше всего использовать обычный цикл for.

var list = [1, 2, 3, 4, 5, /* ...... */ 100000000]
for (var i = 0, l = list.length; i < l; i++) {
  console.log(list[i])
}

В примере выше есть один дополнительный приём, с помощью которого кэшируется величина длины массива: l = list.length.

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

Фактически, отсутствие кэширования может привести к выполнению цикла в два раза медленнее, чем при кэшировании длины

Свойство length

Хотя геттер свойства length просто возвращает количество элементов содержащихся в массиве, сеттер можно использовать для обрезания массива.

var foo = [1, 2, 3, 4, 5, 6]
foo.length = 3
foo // [1, 2, 3]

foo.length = 6
foo // [1, 2, 3]

Присвоение свойству length меньшей величины урезает массив, однако присвоение большего значения не даст никакого эффекта.

Заключение

Для оптимальной работы кода рекомендуется всегда использовать простой цикл for и кэшировать свойство length. Использование for in с массивами является признаком плохого кода, обладающего предпосылками к ошибкам и может привести к низкой скорости его выполнения.