Цикл по массиву в JavaScript
В Java вы можете использовать цикл for
для перебора объектов в массиве следующим образом:
String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray) {
// Выполнить какое-то действие
}
Можно ли сделать то же самое в JavaScript?
4 ответ(ов)
В вашем вопросе приведены два различных цикла: один для перебора массивов, а другой для перебора объектов. Вот их перевод на русский язык с дополнениями:
Цикл по массиву:
for (var i = 0; i < things.length; i++) {
var thing = things[i];
console.log(thing);
}
В этом примере мы используем классический цикл for
, чтобы перебрать элементы массива things
. Мы инициализируем переменную i
равной 0, затем продолжаем цикл, пока i
меньше длины массива. На каждой итерации мы получаем текущий элемент массива по индексу i
и выводим его в консоль.
Цикл по объекту:
for (var prop in obj) {
var propValue = obj[prop];
console.log(propValue);
}
В этом примере мы используем цикл for...in
, который предназначен для перебора свойств объекта obj
. На каждой итерации мы берем имя текущего свойства (переменная prop
) и получаем его значение. Затем мы выводим это значение в консоль. Обратите внимание, что for...in
будет перебирать все перечисляемые свойства объекта, включая наследуемые.
Если вам нужно перебрать только собственные свойства объекта (без наследования), вы можете использовать метод Object.keys()
или Object.entries()
, чтобы получить массив ключей или пар [ключ, значение]. Например:
Object.keys(obj).forEach(function(prop) {
console.log(obj[prop]);
});
Или с использованием Object.entries()
:
Object.entries(obj).forEach(function([key, value]) {
console.log(value);
});
Это позволит вам избежать неожиданных результатов из-за свойств, унаследованных от прототипа.
Если вы используете библиотеку jQuery, рассмотрите возможность использования функции jQuery.each( коллекция, колбэк(индексВМассиве, значениеЭлемента) ).
Из документации:
jQuery.each( collection, callback(indexInArray, valueOfElement) )
Возвращает: Объект
Описание: Универсная функция итератора, которую можно бесшовно использовать для перебора как объектов, так и массивов. Массивы и объекты, похожие на массивы, с свойством length (такие как объект аргументов функции), перебираются по числовым индексам, от 0 до length-1. Другие объекты перебираются через их именованные свойства.
Функция $.each()
не является тем же самым, что $(селектор).each()
, которая используется исключительно для перебора jQuery-объекта. Функцию $.each()
можно использовать для перебора любой коллекции, будь то карта (объект JavaScript) или массив. В случае массива колбэк получает индекс массива и соответствующее значение массива каждый раз. (Значение также можно получить через ключевое слово this
, но JavaScript всегда оборачивает значение this
в Object
, даже если это простая строка или число.) Метод возвращает свой первый аргумент — объект, который был перебран.
Я ещё не видел этой вариации, которая, на мой взгляд, является самой удачной:
Имеется массив:
var someArray = ["некоторый", "пример", "массива"];
Вы можете пройтись по нему, не обращаясь к свойству length:
for (var i = 0, item; item = someArray[i]; i++) {
// item будет "некоторый", затем "пример", затем "массива"
// i - это индекс item в массиве
alert("someArray[" + i + "]: " + item);
}
Вот ссылка на JsFiddle, демонстрирующий это: http://jsfiddle.net/prvzk/
Этот подход работает только для массивов, которые не являются разреженными. То есть, в массиве действительно должно быть значение по каждому индексу. Однако, на практике я почти никогда не использую разреженные массивы в JavaScript... В таких случаях обычно намного проще использовать объект в качестве карты/хэш-таблицы. Если же у вас есть разреженный массив и нужно пройтись по индексам от 0 до length-1, вам потребуется конструкция for (var i = 0; i < someArray.length; ++i)
, но при этом всё равно нужно использовать if
внутри цикла, чтобы проверить, действительно ли элемент с текущим индексом определён.
Также, как упоминает CMS в комментарии ниже, вы можете использовать этот подход только для массивов, которые не содержат ложных значений. Массив строк из примера работает, но если у вас есть пустые строки, числа 0 или NaN и т.д., то цикл завершится преждевременно. Впрочем, на практике для меня это почти никогда не бывает проблемой, но стоит иметь это в виду, что делает этот цикл тем, о котором следует подумать перед его использованием... Это может оттолкнуть некоторых людей 😃
Что мне нравится в этом цикле:
- Его легко писать
- Нет необходимости обращаться (не говоря уже о кэшировании) к свойству length
- Элемент, к которому нужно обратиться, автоматически определяется в теле цикла под выбранным вами именем.
- Очень естественно комбинируется с массивами через array.push и array.splice, что позволяет использовать массивы как списки/стеки
Причина, по которой это работает, заключается в том, что спецификация массива требует, чтобы при чтении элемента по индексу, больше или равному длине массива, возвращалось значение undefined. При записи в такую ячейку длина массива фактически обновляется.
Для меня эта конструкция наиболее близка к синтаксису Java 5, который я очень люблю:
for (String item : someArray) {
}
... с дополнительным преимуществом, что мы также знаем текущий индекс внутри цикла.
В JavaScript существует способ перебора только собственных свойств объекта, не включая свойства его прототипа. Это можно сделать с помощью следующего кода:
for (var i in array) if (array.hasOwnProperty(i)) {
// Выполняем какие-то действия с array[i]
}
Однако стоит отметить, что данный метод будет также перебирать пользовательские свойства, которые могли быть добавлены к объекту.
Говоря о массивах, важно помнить, что в JavaScript вы можете назначать любые произвольные свойства любому объекту, включая массивы. Если вам нужно пройтись по "разреженному" массиву (где есть пропуски в индексах), рекомендуется использовать другой подход. Например, вы можете использовать цикл for
с проверкой, есть ли индекс в массиве:
for (var i = 0; i < array.length; i++) if (i in array) {
// Обработка array[i]
}
Также можно использовать метод forEach
, особенно если вы подключили полифил, например, es5shim
, который позволит использовать forEach
на IE8 и старше:
array.forEach(function(item) {
// Обработка item
});
Таким образом, для корректного перебора элементов разреженного массива лучше использовать один из указанных выше подходов.
Как перебрать или перечислить объекты в JavaScript?
Как перемешать (сделать случайным) массив в JavaScript?
Как объединить два массива в JavaScript и удалить дубликаты?
Как очистить массив в JavaScript?
Выбор последнего элемента в массиве JavaScript