40

Цикл по массиву в JavaScript

13

В Java вы можете использовать цикл for для перебора объектов в массиве следующим образом:

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray) {
    // Выполнить какое-то действие
}

Можно ли сделать то же самое в JavaScript?

4 ответ(ов)

0

В вашем вопросе приведены два различных цикла: один для перебора массивов, а другой для перебора объектов. Вот их перевод на русский язык с дополнениями:

Цикл по массиву:

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);
});

Это позволит вам избежать неожиданных результатов из-за свойств, унаследованных от прототипа.

0

Если вы используете библиотеку jQuery, рассмотрите возможность использования функции jQuery.each( коллекция, колбэк(индексВМассиве, значениеЭлемента) ).

Из документации:

jQuery.each( collection, callback(indexInArray, valueOfElement) )

Возвращает: Объект

Описание: Универсная функция итератора, которую можно бесшовно использовать для перебора как объектов, так и массивов. Массивы и объекты, похожие на массивы, с свойством length (такие как объект аргументов функции), перебираются по числовым индексам, от 0 до length-1. Другие объекты перебираются через их именованные свойства.

Функция $.each() не является тем же самым, что $(селектор).each(), которая используется исключительно для перебора jQuery-объекта. Функцию $.each() можно использовать для перебора любой коллекции, будь то карта (объект JavaScript) или массив. В случае массива колбэк получает индекс массива и соответствующее значение массива каждый раз. (Значение также можно получить через ключевое слово this, но JavaScript всегда оборачивает значение this в Object, даже если это простая строка или число.) Метод возвращает свой первый аргумент — объект, который был перебран.

0

Я ещё не видел этой вариации, которая, на мой взгляд, является самой удачной:

Имеется массив:

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) {
}

... с дополнительным преимуществом, что мы также знаем текущий индекс внутри цикла.

0

В 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
});

Таким образом, для корректного перебора элементов разреженного массива лучше использовать один из указанных выше подходов.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь