--- title: for...in slug: Web/JavaScript/Reference/Statements/for...in tags: - JavaScript - Выражение - Цикл translation_of: Web/JavaScript/Reference/Statements/for...in ---
Цикл for...in
проходит через перечисляемые свойства объекта. Он пройдёт по каждому отдельному элементу.
for (variable in object) {... }
variable
object
Цикл for...in
проходит только по перечисляемым свойствам. Объекты, созданные встроенными конструкторами, такими как Array
и Object
имеют неперечисляемые свойства от Object.prototype
и String.prototype
, например, от {{jsxref("String")}}-это {{jsxref("String.indexOf", "indexOf()")}}, а от {{jsxref("Object")}} - метод {{jsxref("Object.toString", "toString()")}}. Цикл пройдёт по всем перечисляемым свойствам объекта, а также тем, что он унаследует от конструктора прототипа (свойства объекта в цепи прототипа).
Цикл for...in
проходит по свойствам в произвольном порядке (см. оператор {{jsxref("Operators/delete", "delete")}} для того, чтобы узнать почему порядок прохода может отличаться в зависимости от браузера). Если свойство изменяется за одну итерацию, а затем изменяется снова, его значением в цикле является его последнее значение. Свойство, удалённое до того, как до него дошёл цикл, не будет участвовать в нём. Свойства добавленные в объекты в цикле могут быть пропущены. В общем, лучше не добавлять, изменять или удалять свойство из объекта во время итерации, если по нему ещё не прошли. Нет гарантии, что добавленное свойство будет посещено циклом, низменное после проведения изменений, а удалённое после удаления.
Проход по массиву и for...in
Замечание: for...in
не следует использовать для {{jsxref("Array")}}, где важен порядок индексов.
Индексы массива - это перечисляемые свойства с целочисленными именами, в остальном они аналогичны свойствам объектов. Нет гарантии, что for...in
будет возвращать индексы в конкретном порядке. Цикл for...in
возвращает все перечисляемые свойства, включая имеющие нецелочислиненные имена и наследуемые.
Так как порядок прохода зависит от реализации, проход по массиву может не произойти в правильном порядке. Следовательно лучше с числовыми индексами использовать циклы {{jsxref("Statements/for", "for")}}, {{jsxref("Array.prototype.forEach()")}} или {{jsxref("Statements/for...of", "for...of")}}, когда проходим по массивам, где важен порядок доступа к свойствам.
Если вы хотите рассматривать только свойства самого объекта, а не его прототипов, используйте {{jsxref("Object.getOwnPropertyNames", "getOwnPropertyNames()")}}, {{jsxref("Object.prototype.hasOwnProperty", "hasOwnProperty()")}} или {{jsxref("Object.prototype.propertyIsEnumerable", "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"
Следующая функция иллюстрирует использование {{jsxref("Object.prototype.hasOwnProperty", "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"
Спецификация | Статус | Комментарий |
---|---|---|
{{SpecName('ES6', '#sec-for-in-and-for-of-statements', 'for...in statement')}} | {{Spec2('ES6')}} | |
{{SpecName('ES5.1', '#sec-12.6.4', 'for...in statement')}} | {{Spec2('ES5.1')}} | |
{{SpecName('ES3', '#sec-12.6.4', 'for...in statement')}} | {{Spec2('ES3')}} | |
{{SpecName('ES1', '#sec-12.6.3', 'for...in statement')}} | {{Spec2('ES1')}} | Изначальное определение |
{{Compat}}
До SpiderMonkey 40 {{geckoRelease(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 и более поздних, оно бросит предупреждение {{jsxref("SyntaxError")}} ("for-in loop head declarations may not have initializers") в консоль ({{bug(748550)}} и {{bug(1164741)}}).
Другие движки, такие как v8 (Chrome), Chakra (IE/Edge) и JSC (WebKit/Safari) также собираются удалить это нестандартное поведение.
for...in
)