--- 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) statement
variableobjectЦикл for...in перебирає лише перелічувані, не символьні властивості. Об'єкти, створені вбудованими конструкторами, як Array та Object, успадковують неперелічувані властивості від Object.prototype та String.prototype, такі як метод {{jsxref("String.indexOf", "indexOf()")}} у {{jsxref("String")}} або метод {{jsxref("Object.toString", "toString()")}} у {{jsxref("Object")}}. Цикл перебиратиме усі особисті перелічувані властивості об'єкта й ті, які об'єкт успадковує від прототипу конструктора (властивості, розташовані ближче до об'єкта у ланцюжку прототипів, заміщують властивості прототипу).
Цикл for...in перебирає властивості об'єкта у довільному порядку (дивіться оператор {{jsxref("Operators/delete", "delete")}}, щоб дізнатись, чому не можна покладатися на удавану впорядкованість перебору, принаймні, у кросбраузерних налаштуваннях).
Якщо властивість була змінена під час однієї ітерації і потім відвідується під час наступної, її значенням у циклі буде значення під час наступної ітерації. Властивість, що була видалена до того, як була відвідана, не буде відвідана пізніше. Властивості, додані до об'єкта під час поточного перебору, можуть бути або відвідані, або пропущені під час цього перебору.
Загалом, краще не додавати, не змінювати й не видаляти властивості об'єкта під час перебору, окрім властивості, що відвідується у даний момент. Немає гарантії, що додана властивість буде відвідана, чи що змінена властивість (якщо це не поточна властивість) буде відвідана до чи після того, як була змінена, чи що видалена властивість не була відвідана до того, як була видалена.
Заувага: цикл 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()")}}). Альтернативно, якщо ви певні, що не буде зовнішнього втручання у код, ви можете розширити вбудовані прототипи методом перевірки.
Враховуючи, що цикл for...in створений для перебору властивостей об'єкта, не рекомендований для використання у масивах, і що існують такі варіанти як Array.prototype.forEach() та for...of, яка взагалі може бути користь від for...in?
Він може бути найбільш практичним для налагодження, оскільки ним легко перевіряти властивості об'єкта (виводячи їх у консоль чи іншим чином). Хоча масиви часто більш зручні для зберігання даних, у ситуаціях, де для роботи з даними потрібні пари ключ-значення (де властивості виконують роль "ключів"), можливі випадки, коли ви захочете перевірити, чи містить якийсь з цих ключів певне значення.
Наведений цикл for...in перебирає усі перелічувані, не символьні властивості об'єкта та виводить рядки імен властивостей та їхніх значень.
var obj = {a: 1, b: 2, c: 3};
for (const 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 (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log(`obj.${prop} = ${obj[prop]}`);
}
}
// Виведе:
// "obj.color = red"
| Специфікація |
|---|
| {{SpecName('ESDraft', '#sec-for-in-and-for-of-statements', 'for...in statement')}} |
{{Compat("javascript.statements.for_in")}}
До Firefox 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)