- for. in
- Синтаксис
- Описание
- Удаление, добавление и модификация свойств
- Проход по массиву и for. in
- Проход только через собственные свойства
- Примеры
- Спецификации
- Поддержка браузерами
- Поддержка: инициализатор переменных
- Смотрите также
- Found a content problem with this page?
- Массив: перебирающие методы
- forEach
- filter
- map
- every/some
- reduce/reduceRight
- Итого
for. in
Цикл for. in проходит через перечисляемые свойства объекта. Он пройдёт по каждому отдельному элементу.
Синтаксис
Другое (очередное) имя свойства назначается переменной на каждой итерации.
Объект, по чьим свойствам мы проходим
Описание
Цикл for. in проходит только по перечисляемым свойствам. Объекты, созданные встроенными конструкторами, такими как Array и Object имеют неперечисляемые свойства от Object.prototype и String.prototype , например, от String -это indexOf() , а от Object — метод toString() . Цикл пройдёт по всем перечисляемым свойствам объекта, а также тем, что он унаследует от конструктора прототипа (свойства объекта в цепи прототипа).
Удаление, добавление и модификация свойств
Цикл for. in проходит по свойствам в произвольном порядке (см. оператор delete для того, чтобы узнать почему порядок прохода может отличаться в зависимости от браузера). Если свойство изменяется за одну итерацию, а затем изменяется снова, его значением в цикле является его последнее значение. Свойство, удалённое до того, как до него дошёл цикл, не будет участвовать в нём. Свойства добавленные в объекты в цикле могут быть пропущены. В общем, лучше не добавлять, изменять или удалять свойство из объекта во время итерации, если по нему ещё не прошли. Нет гарантии, что добавленное свойство будет посещено циклом, низменное после проведения изменений, а удалённое после удаления.
Проход по массиву и for. in
Примечание: for. in не следует использовать для Array , где важен порядок индексов.
Индексы массива — это перечисляемые свойства с целочисленными именами, в остальном они аналогичны свойствам объектов. Нет гарантии, что for. in будет возвращать индексы в конкретном порядке. Цикл for. in возвращает все перечисляемые свойства, включая имеющие нецелочислиненные имена и наследуемые.
Так как порядок прохода зависит от реализации, проход по массиву может не произойти в правильном порядке. Следовательно лучше с числовыми индексами использовать циклы for , Array.prototype.forEach() или for. of , когда проходим по массивам, где важен порядок доступа к свойствам.
Проход только через собственные свойства
Если вы хотите рассматривать только свойства самого объекта, а не его прототипов, используйте getOwnPropertyNames() , hasOwnProperty() или propertyIsEnumerable . Кроме того, если вы знаете, что не будет вмешательства в код извне, вы можете расширить встроенные прототипы методом проверки.
Примеры
Следующее выражение берёт аргументом объект. Затем проходит по всем перечислимым свойствам объекта и возвращает строку содержащую имена свойств и их значения.
var obj = a:1, b:2, c:3>; for (var prop in obj) console.log("obj." + prop + " token operator">+ obj[prop]); > // Выведет: // "obj.a = 1" // "obj.b = 2" // "obj.c = 3"
Следующая функция иллюстрирует использование hasOwnProperty() : наследуемые свойства не отображаются
var triangle = a:1, b:2, c:3>; function ColoredTriangle() this.color = "red"; > ColoredTriangle.prototype = triangle; var obj = new ColoredTriangle(); for (var prop in obj) if( obj.hasOwnProperty( prop ) ) console.log("obj." + prop + " token operator">+ obj[prop]); > > // Выведет: // "obj.color = red"
Спецификации
Спецификация | Статус | Комментарий |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Определение ‘for. in statement’ в этой спецификации. | Стандарт | |
ECMAScript 5.1 (ECMA-262) Определение ‘for. in statement’ в этой спецификации. | Стандарт | |
ECMAScript 3rd Edition (ECMA-262) Определение ‘for. in statement’ в этой спецификации. | Стандарт | |
ECMAScript 1st Edition (ECMA-262) Определение ‘for. in statement’ в этой спецификации. | Стандарт | Изначальное определение |
Поддержка браузерами
BCD tables only load in the browser
Поддержка: инициализатор переменных
До SpiderMonkey 40, можно было инициализировать переменные ( i=0 ) в цикле for. in :
var obj = a:1, b:2, c:3>; for(var i=0 in obj) console.log(obj[i]); > // 1 // 2 // 3
Это нестандартное поведение игнорируется в версии 40 и более поздних, оно бросит предупреждение SyntaxError («for-in loop head declarations may not have initializers») в консоль (баг 748550 и баг 1164741).
Другие движки, такие как v8 (Chrome), Chakra (IE/Edge) и JSC (WebKit/Safari) также собираются удалить это нестандартное поведение.
Смотрите также
- for. of — похожий цикл, проходящий по значениям свойств
- for each in — похожее выражение, но перебирает значения свойств, а не их имена (устарело)
- for
- Генераторы (использующие синтаксис for. in )
- Перечислимость и владение свойствами
- Object.getOwnPropertyNames()
- Object.prototype.hasOwnProperty()
- Array.prototype.forEach()
Found a content problem with this page?
This page was last modified on 15 июл. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Массив: перебирающие методы
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/array-methods.
Современный стандарт JavaScript предоставляет много методов для «умного» перебора массивов, которые есть в современных браузерах…
…Ну а для их поддержки в IE8- просто подключите библиотеку ES5-shim.
forEach
Метод «arr.forEach(callback[, thisArg])» используется для перебора массива.
Он для каждого элемента массива вызывает функцию callback .
Этой функции он передаёт три параметра callback(item, i, arr) :
- item – очередной элемент массива.
- i – его номер.
- arr – массив, который перебирается.
var arr = ["Яблоко", "Апельсин", "Груша"]; arr.forEach(function(item, i, arr) < alert( i + ": " + item + " (массив:" + arr + ")" ); >);
Второй, необязательный аргумент forEach позволяет указать контекст this для callback . Мы обсудим его в деталях чуть позже, сейчас он нам не важен.
Метод forEach ничего не возвращает, его используют только для перебора, как более «элегантный» вариант, чем обычный цикл for .
filter
Метод «arr.filter(callback[, thisArg])» используется для фильтрации массива через функцию.
Он создаёт новый массив, в который войдут только те элементы arr , для которых вызов callback(item, i, arr) возвратит true .
var arr = [1, -1, 2, -2, 3]; var positiveArr = arr.filter(function(number) < return number >0; >); alert( positiveArr ); // 1,2,3
map
Метод «arr.map(callback[, thisArg])» используется для трансформации массива.
Он создаёт новый массив, который будет состоять из результатов вызова callback(item, i, arr) для каждого элемента arr .
var names = ['HTML', 'CSS', 'JavaScript']; var nameLengths = names.map(function(name) < return name.length; >); // получили массив с длинами alert( nameLengths ); // 4,3,10
every/some
Эти методы используются для проверки массива.
- Метод «arr.every(callback[, thisArg])» возвращает true , если вызов callback вернёт true для каждого элемента arr .
- Метод «arr.some(callback[, thisArg])» возвращает true , если вызов callback вернёт true для какого-нибудь элемента arr .
var arr = [1, -1, 2, -2, 3]; function isPositive(number) < return number >0; > alert( arr.every(isPositive) ); // false, не все положительные alert( arr.some(isPositive) ); // true, есть хоть одно положительное
reduce/reduceRight
Метод «arr.reduce(callback[, initialValue])» используется для последовательной обработки каждого элемента массива с сохранением промежуточного результата.
Это один из самых сложных методов для работы с массивами. Но его стоит освоить, потому что временами с его помощью можно в несколько строк решить задачу, которая иначе потребовала бы в разы больше места и времени.
Метод reduce используется для вычисления на основе массива какого-либо единого значения, иначе говорят «для свёртки массива». Чуть далее мы разберём пример для вычисления суммы.
Он применяет функцию callback по очереди к каждому элементу массива слева направо, сохраняя при этом промежуточный результат.
Аргументы функции callback(previousValue, currentItem, index, arr) :
- previousValue – последний результат вызова функции, он же «промежуточный результат».
- currentItem – текущий элемент массива, элементы перебираются по очереди слева-направо.
- index – номер текущего элемента.
- arr – обрабатываемый массив.
Кроме callback , методу можно передать «начальное значение» – аргумент initialValue . Если он есть, то на первом вызове значение previousValue будет равно initialValue , а если у reduce нет второго аргумента, то оно равно первому элементу массива, а перебор начинается со второго.
Проще всего понять работу метода reduce на примере.
Например, в качестве «свёртки» мы хотим получить сумму всех элементов массива.
Вот решение в одну строку:
var arr = [1, 2, 3, 4, 5] // для каждого элемента массива запустить функцию, // промежуточный результат передавать первым аргументом далее var result = arr.reduce(function(sum, current) < return sum + current; >, 0); alert( result ); // 15
Разберём, что в нём происходит.
При первом запуске sum – исходное значение, с которого начинаются вычисления, равно нулю (второй аргумент reduce ).
Сначала анонимная функция вызывается с этим начальным значением и первым элементом массива, результат запоминается и передаётся в следующий вызов, уже со вторым аргументом массива, затем новое значение участвует в вычислениях с третьим аргументом и так далее.
Поток вычислений получается такой
В виде таблицы где каждая строка – вызов функции на очередном элементе массива:
sum | current | результат | |
---|---|---|---|
первый вызов | 0 | 1 | 1 |
второй вызов | 1 | 2 | 3 |
третий вызов | 3 | 3 | 6 |
четвёртый вызов | 6 | 4 | 10 |
пятый вызов | 10 | 5 | 15 |
Как видно, результат предыдущего вызова передаётся в первый аргумент следующего.
Кстати, полный набор аргументов функции для reduce включает в себя function(sum, current, i, array) , то есть номер текущего вызова i и весь массив arr , но здесь в них нет нужды.
Посмотрим, что будет, если не указать initialValue в вызове arr.reduce :
var arr = [1, 2, 3, 4, 5] // убрали 0 в конце var result = arr.reduce(function(sum, current) < return sum + current >); alert( result ); // 15
Результат – точно такой же! Это потому, что при отсутствии initialValue в качестве первого значения берётся первый элемент массива, а перебор стартует со второго.
Таблица вычислений будет такая же, за вычетом первой строки.
Метод arr.reduceRight работает аналогично, но идёт по массиву справа-налево.
Итого
- forEach – для перебора массива.
- filter – для фильтрации массива.
- every/some – для проверки массива.
- map – для трансформации массива в массив.
- reduce/reduceRight – для прохода по массиву с вычислением значения.
Во многих ситуациях их использование позволяет написать код короче и понятнее, чем обычный перебор через for .