Цикл for...in проходит через перечисляемые свойства объекта. Он пройдёт по каждому отдельному элементу.
Синтаксис
for (variable in object) {...
}
variable- Другое (очередное) имя свойства назначается переменной на каждой итерации.
object- Объект, по чьим свойствам мы проходим
Описание
Цикл 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 + " = " + 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 + " = " + 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' в этой спецификации. |
Стандарт | Изначальное определение |
Поддержка браузерами
| Возможность | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Базовая поддержка | (Да) | (Да) | (Да) | (Да) | (Да) |
| Возможность | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Базовая поддержка | (Да) | (Да) | (Да) | (Да) | (Да) | (Да) |
Поддержка: инициализатор переменных
До SpiderMonkey 40 (Firefox 40 / Thunderbird 40 / SeaMonkey 2.37), можно было инициализировать переменные (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()