Да, если ваша реализация включает for
...of
функцию, представленную в ECMAScript 2015 (выпуск "Harmony") ... который в наши дни является довольно безопасным предположением.
Это работает так:
// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
// ... do something with s ...
}
Или еще лучше, так как ECMAScript 2015 также предоставляет переменные в области блока:
// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
// ... do something with s ...
}
// s is no longer defined here
(Переменная s
отличается на каждой итерации, но все еще может быть объявлена const
внутри тела цикла, если она там не изменена.)
Замечание о разреженных массивах: массив в JavaScript может на самом деле не хранить столько элементов, сколько сообщил его length
; это сообщаемое число просто на единицу больше, чем самый высокий индекс, при котором хранится значение. Если массив содержит меньше элементов, чем указано в его длине, он называется разреженным . Например, вполне допустимо иметь массив с элементами только по индексам 3, 12 и 247; в s для любых недостающих элементов, или вы хотите обрабатывать только элементы фактически присутствующие? Существует множество приложений для обоих подходов; это зависит только от того, для чего вы используете массив.length
такого массива сообщается как 248, хотя на самом деле только хранить 3 значения. Если вы попытаетесь получить доступ к элементу по какому-либо другому индексу, массив будет иметь undefined
значение там. Поэтому, когда вы хотите «пройтись» по массиву, у вас возникает вопрос: хотите ли вы пройтись по всему диапазону, указанному его длиной и процессом?undefined
Если вы выполняете итерацию массива с помощью for
.. of
, тело цикла выполняется length
раз, а для переменной управления цикла устанавливается значение undefined
для любых элементов, фактически не представленных в массиве. В зависимости от деталей вашего кода «делать что-то», такое поведение может быть тем, что вам нужно, но если нет, вам следует использовать другой подход.
Конечно, некоторые разработчики не имеют иного выбора , кроме как использовать другой подход в любом случае, потому что по какой - то причине они ориентации версию JavaScript , который еще не поддерживается for
... of
.
Пока ваша реализация JavaScript совместима с предыдущей версией спецификации ECMAScript (которая исключает, например, версии Internet Explorer до 9), вы можете использовать Array#forEach
метод итератора вместо цикла. В этом случае вы передаете функцию, которая будет вызываться для каждого элемента в массиве:
var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) {
// ... do something with s ...
} );
В отличие от for
... of
, .forEach
вызывает функцию только для элементов, которые действительно присутствуют в массиве. Если передать наш гипотетический массив с тремя элементами и длиной 248, он будет вызывать функцию только три раза, а не 248 раз. Он также различает отсутствующие элементы и элементы, которые на самом деле установлены undefined
; для последнего он по-прежнему будет вызывать функцию, передавая undefined
в качестве аргумента. Если это, как вы хотите обрабатывать разреженные массивы, .forEach
может быть путь , даже если интерпретатор поддерживает for
... of
.
Последний вариант, который работает во всех версиях JavaScript, - это явный цикл подсчета . Вы просто считаете от 0 до единицы меньше длины и используете счетчик в качестве индекса. Основной цикл выглядит так:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
s = myStringArray[i];
// ... do something with s ...
}
Одним из преимуществ этого подхода является то, что вы можете выбрать способ обработки разреженных массивов; приведенный выше код будет работать тело цикла полные length
раз, с s
набором для undefined
любых недостающих элементов, так же как for
.. of
. Если вы вместо этого хотите обрабатывать только реально существующие элементы разреженного массива, например .forEach
, вы можете добавить простой in
тест в индекс:
var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
if (i in myStringArray) {
s = myStringArray[i];
// ... do something with s ...
}
}
Присвоение значения длины локальной переменной (в отличие от включения полного myStringArray.length
выражения в условие цикла) может существенно повлиять на производительность, поскольку оно пропускает поиск свойств каждый раз; при использовании Rhino на моей машине ускорение составляет 43%.
Вы можете увидеть, что кэширование длины выполняется в предложении инициализации цикла, например так:
var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {
Явный цикл подсчета также означает, что у вас есть доступ к индексу каждого значения, если вы этого хотите. Индекс также передается в качестве дополнительного параметра функции, которую вы передаетеforEach
, так что вы также можете получить к нему доступ таким образом:
myStringArray.forEach( function(s, i) {
// ... do something with s and i ...
});
for
... of
не дает индекс, связанный с каждым объектом, но пока объект, над которым вы перебираете, фактически является Array
( for
.. of
работает для других повторяемых типов, которые могут не иметь этого метода), вы можете использовать массив Метод #entries, чтобы изменить его на массив пар [index, item], а затем выполнить итерацию:
for (const [i, s] of myStringArray.entries()) {
// ... do something with s and i ...
}
for
... in
синтаксис уже отмечалось другими для цикла по свойствам объекта; так как массив в JavaScript - это просто объект с числовыми именами свойств (и автоматически обновляемым length
свойством), вы можете теоретически зациклить массив с ним. Но проблема заключается в том, что он не ограничивается числовыми значениями свойств (помните, что даже методы на самом деле являются просто свойствами, значение которых является замыканием), и при этом не гарантируется, что они будут повторяться в числовом порядке. Следовательно, синтаксис for
... не должен использоваться для циклического перемещения по массивам.in