Javascript foreach для объекта

Все способы перебора массива в JavaScript

Если ваш проект рассчитан на поддержку возможностей стандарта ECMAScript 5 (ES5), вы можете использовать одно из его нововведений — метод forEach.

var a = ["a", "b", "c"]; a.forEach(function(entry) < console.log(entry); >); 

В общем случае использование forEach требует подключения библиотеки эмуляции es5-shim для браузеров, не имеющих нативной поддержки этого метода. К ним относятся IE 8 и более ранние версии, которые до сих пор кое-где еще используются.

К достоинствам forEach относится то, что здесь не нужно объявлять локальные переменные для хранения индекса и значения текущего элемента массива, поскольку они автоматически передаются в функцию обратного вызова (колбек) в качестве аргументов.

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

  • every — возвращает true , если для каждого элемента массива колбек возвращает значение приводимое к true .
  • some — возвращает true , если хотя бы для одного элемента массива колбек возвращает значение приводимое к true .
  • filter — создает новый массив, включающий те элементы исходного массива, для которых колбек возвращает true .
  • map — создает новый массив, состоящий из значений возращаемых колбеком.
  • reduce — сводит массив к единственному значению, применяя колбек по очереди к каждому элементу массива, начиная с первого (может быть полезен для вычисления суммы элементов массива и других итоговых функций).
  • reduceRight — работает аналогично reduce, но перебирает элементы в обратном порядке.
Читайте также:  Python numpy array удалить элемент

2. Цикл for

Старый добрый for рулит:

var a = ["a", "b", "c"]; var index; for (index = 0; index

Если длина массива неизменна в течение всего цикла, а сам цикл принадлежит критическому в плане производительности участку кода (что маловероятно), то можно использовать «более оптимальную» версию for с хранением длины массива:

var a = ["a", "b", "c"]; var index, len; for (index = 0, len = a.length; index

Теоретически этот код должен выполняться чуть быстрее, чем предыдущий.

Если порядок перебора элементов не важен, то можно пойти еще дальше в плане оптимизации и избавиться от переменной для хранения длины массива, изменив порядок перебора на обратный:

var a = ["a", "b", "c"]; var index; for (index = a.length - 1; index >= 0; --index)

Тем не менее, в современных движках JavaScript подобные игры с оптимизацией обычно ничего не значат.

3. Правильное использование цикла for. in

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

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

// a - разреженный массив var a = []; a[0] = "a"; a[10] = "b"; a[10000] = "c"; for (var key in a) < if (a.hasOwnProperty(key) && /^0$|^5\d*$/.test(key) && key > 
  1. то, что массив имеет собственное свойство с именем key (не наследованное из его прототипа).
  2. то, что key — строка, содержащая десятичную запись целого числа, значение которого меньше 4294967294 . Откуда берется последнее число? Из определения индекса массива в ES5, из которого следует, что наибольший индекс, который может иметь элемент в массиве: (2^32 — 2) = 4294967294 .

Чтобы не писать такой громоздкий код проверок каждый раз, когда требуется перебор массива, можно оформить его в виде отдельной функции:

function arrayHasOwnIndex(array, key) < return array.hasOwnProperty(key) && /^0$|^4\d*$/.test(key) && key

Тогда тело цикла из примера значительно сократится:

Рассмотренный выше код проверок является универсальным, подходящим для всех случаев. Но вместо него можно использовать более короткую версию, хотя формально и не совсем правильную, но, тем не менее, подходящую для большинства случаев:

4. Цикл for. of (неявное использование итератора)

ES6, пока все еще пребывающий в статусе черновика, должен ввести в JavaScript итераторы.

  1. done ( boolean ) — принимает значение true , если итератор достиг конца итерируемой последовательности. В противном случае имеет значение false .
  2. value — определяет значение, возвращаемое итератором. Может быть не определено (отсутствовать), если свойство done имеет значение true .

Пример использования for. of :

var val; var a = ["a", "b", "c"]; for (val of a)

В приведенном примере цикл for. of неявно вызывает итератор объекта Array для получения каждого значения массива.

5. Явное использование итератора

Итераторы можно также использовать и явно, правда, в этом случае код становится значительно сложнее, по сравнению с циклом for. of . Выглядит это примерно так:

var a = ["a", "b", "c"]; var it = a.entries(); var entry; while (!(entry = it.next()).done)

В данном примере метод Array.prototype.entries возвращает итератор, который используется для вывода значений массива. На каждой итерации entry.value содержит массив вида [ключ, значение] .

II. Перебор массивоподобных объектов

Кроме настоящих массивов, в JavaScript встречаются также массивоподобные объекты. С настоящими массивами их роднит то, что они имеют свойство length и свойства с именами в виде чисел, соответствующие элементам массива. В качестве примеров можно назвать DOM коллекции NodeList и псевдомассив arguments , доступный внутри любой функции/метода.

1. Использование способов перебора настоящих массивов

Как минимум большинство, если не все, способы перебора настоящих массивов могут быть применены для перебора массивоподобных объектов.

Конструкции for и for. in могут быть применены к массивоподобным объектам точно тем же путем, что и к настоящим массивам.

forEach и другие методы Array.prototype также применимы к массивоподобным объектам. Для этого нужно использовать вызов Function.call или Function.apply.

Например, если вы хотите применить forEach к свойству childNodes объекта Node , то это делается так:

Array.prototype.forEach.call(node.childNodes, function(child) < // делаем что-нибудь с объектом child >); 

Для удобства повторного использования этого приема, можно объявить ссылку на метод Array.prototype.forEach в отдельной переменной и использовать ее как сокращение:

// (Предполагается, что весь код ниже находится в одной области видимости) var forEach = Array.prototype.forEach; // . forEach.call(node.childNodes, function(child) < // делаем что-нибудь с объектом child >); 

Если в массивоподобном объекте имеется итератор, то его можно использовать явно или неявно для перебора объекта таким же способом, как и для настоящих массивов.

2. Преобразование в настоящий массив

Есть также еще один, очень простой, способ перебора массивоподобного объекта: преобразовать его в настоящий массив и использовать любой из рассмотренных выше способов перебора настоящих массивов. Для преобразования можно использовать универсальный метод Array.prototype.slice , который может быть применен к любому массивоподобному объекту. Делается это очень просто, как показано в примере ниже:

var trueArray = Array.prototype.slice.call(arrayLikeObject, 0); 

Например, если вы хотите преобразовать коллекцию NodeList в настоящий массив, вам нужен примерно такой код:

var divs = Array.prototype.slice.call(document.querySelectorAll("div"), 0); 

Update: Как было отмечено в комментариях rock и torbasow, в ES6 вместо Array.prototype.slice можно использовать более наглядный метод Array.from .

3. Замечание по объектам среды исполнения

Если вы применяете методы Array.prototype к объектам среды исполнения (таких как DOM коллекции), то вы должны иметь в виду, что правильная работа этих методов не гарантирована во всех средах исполнения (в т.ч. в браузерах). Это зависит от поведения конкретного объекта в конкретной среде исполнения, если точнее, от того, как в этом объекте реализована абстрактная операция HasProperty . Проблема в том, что сам стандарт ES5 допускает возможность неправильного поведения объекта по отношению к этой операции (см. §8.6.2).

Поэтому важно тестировать работу методов Array.prototype в каждой среде исполнения (браузере), в которой планируется использование вашего приложения.

Источник

Javascript foreach для объекта

Методы перебора объектов с помощью javascript | How to loop through objects keys and values in Javascript

Распространенная проблема, с которой сталкиваются программисты - это как перебрать набор данных. Эти данные могут поступать в виде массивов, списков, таблиц или других объектов. В этой статье мы рассмотрим эту проблему и узнаем 4 способа перебора объектов с помощью Javascript для получения необходимых пар ключ-значение.

Перебор объекта обычными способами

Если у вас есть массив данных, который является объектом в Javascript, вы не сможете перебрать его с помощью таких методов, как map() , forEach() или цикла for..of . Вы просто получите ошибку.

map() выдаст вам TypeError: items.map is not a function:

forEach() выдаст вам TypeError: items.forEach is not a function:

for..of выдаст вам TypeError: items are not iterable:

Методы для перебора объектов в Javascript

Цикл for. in

Самый простой способ перебрать свойства объекта - использовать оператор for. in . Этот метод работает во всех современных и старых браузерах, включая Internet Explorer 6 и выше.

Вот пример, в котором цикл for. in используется для перебора объекта:

const user = < name: 'Иван Пeтров', email: 'petrov@mail.com', age: 25, date: '08/02/1989', active: true >; for (const key in user) < console.log(key + ':', userJavascript foreach для объекта); >// name: Иван Пeтров // email: petrov@mail.com // age: 25 // date: 08/02/1989 // active: true

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

Чтобы избежать этой проблемы, необходимо явно проверить, принадлежит ли свойство объекту, используя метод hasOwnProperty() :

Чтобы преодолеть эту проблему, позже в ES8 были добавлены два других метода: Object.entries() и Object.values() . Эти методы преобразовывают объект в массив, чтобы потом использовать методы перебора массива.

Метод Object.keys()

До спецификации ES6 единственным способом перебрать объект был цикл for. in . Метод Object.keys() был введен в ES6, чтобы упростить перебор объектов.

Он принимает объект, который вы хотите перебрать в качестве аргумента, и возвращает массив, содержащий все имена свойств (или ключи). После этого вы можете использовать любой из методов перебора массива, например forEach() , для перемещения по массиву и получения значения каждого свойства.

const courses = < java: 10, javascript: 55, nodejs: 5, php: 15 >; const keys = Object.keys(courses); console.log(keys); // [ 'java', 'javascript', 'nodejs', 'php' ] keys.forEach((key, index) => < console.log(key + ':', coursesJavascript foreach для объекта); >); // java: 10 // javascript: 55 // nodejs: 5 // php: 15

Метод Object.values()

Метод Object.values() был введен в ES8 и работает противоположно методу Object.key() . Он возвращает значения всех свойств объекта в виде массива. Затем вы можете перебрать полученный массив, используя любой из методов цикла.

Давайте посмотрим на примере:

const animals = < tiger: 1, cat: 2, monkey: 3, elephant: 4 >; Object.values(animals).forEach(val => console.log(val)); // 1 // 2 // 3 // 4

Метод Object.entries()

Метод ES8 Object.entries() используется для преобразования объекта. Object.entries() выводит массив массивов, где каждый внутренний массив состоит из двух элементов. Первый элемент - это свойство, а второй - значение.

const animals = < tiger: 1, cat: 2, monkey: 3, elephant: 4 >; const entries = Object.entries(animals); console.log(entries); // [ [ 'tiger', 1 ], [ 'cat', 2 ], [ 'monkey', 3 ], [ 'elephant', 4 ] ]

А уже чтобы перебрать массив, возвращаемый Object.entries() , вы можете использовать цикл for. of или метод forEach() :

// `for. of` цикл for (const Javascript foreach для объекта of Object.entries(animals)) < console.log(key, value); >// `forEach()` метод Object.entries(animals).forEach((Javascript foreach для объекта) => < console.log(key, value) >);

Заключение

Мы вкратце рассмотрели 4 различных способа перебора объектов в Javascript. Если вы используете старые браузеры, for. in по-прежнему является хорошим вариантом; в противном случае вы можете использовать любой из новых методов, описанных выше.

Источник

Оцените статью