for...in

Інструкція for...in ("для кожного ... у") ітерує всі перелічувані рядкові властивості об'єкта (ігноруючи ті, ключами яких є символи), в тому числі успадковані перелічувані властивості.

Спробуйте його в дії

Синтаксис

for (variable in object)
  statement

Параметри

variable

На кожній ітерації отримує ім'я рядкової властивості. Може бути або оголошенням з const, let чи var, або ціллю присвоєння (наприклад, заздалегідь оголошеною змінною чи властивістю об'єкта).

object

Об'єкт, чиї перелічувані властивості з несимвольними ключами перебираються.

statement

Інструкція, що виконається на кожній ітерації. Може звертатися до variable. Для виконання декількох інструкцій можна використати блокову інструкцію.

Опис

Цикл опрацює всі власні перелічувані властивості об'єкта, а також ті, що успадковуються об'єктом від його прототипного ланцюжка (властивості ближчих прототипів мають перевагу над властивостями тих прототипів, які знаходяться далі від об'єкта у ланцюжку прототипів).

Цикл for...in перебирає лише перелічувані несимвольні властивості. Об'єкти, які створюються за допомогою таких вбудованих конструкторів, як Array і Object, мають неперелічувані властивості, успадковані від Array.prototype та Object.prototype, як от метод indexOf() об'єкта Array чи метод toString() об'єкта Object. Такі властивості не оброблятимуться циклом for...in.

Порядок перебирання властивостей, згідно зі сучасною специфікацією ECMAScript — чітко визначений, і незмінний між реалізаціями. Всередині кожного компонента прототипного ланцюжка всі ключі, які є додатними цілими числами (зазвичай це індекси масивів) опрацьовуються першими, в порядку зростання числового значення. Потім опрацьовуються інші рядкові ключі, в хронологічному порядку відносно дати створення кожної властивості.

Частина for...in variable приймає що завгодно, що може стояти зліва оператора =. Якщо не робити присвоєння змінній всередині тіла циклу, то можна для її оголошення використати const (таке присвоєння не вплине на наступну ітерацію, адже в ній буде геть окрема змінна). Інакше – можна використати let. Також можна застосувати деструктурування чи властивість об'єкта, як то for (x.y in iterable).

Застарілий синтаксис дозволяє оголошенням var змінної циклу мати ініціалізатор. Це викидає синтаксичну помилку в строгому режимі й ігнорується в нестрогому.

Видалені, додані чи змінені властивості

Якщо під час однієї з ітерацій властивість змінюється, а потім опрацьовується в одній з наступних ітерацій, в циклі буде використано те значення, яке вона має на момент її опрацювання другого разу. Властивість, яку було видалено перед своєю обробкою, пізніше оброблено не буде. Властивості, які додаються до об'єкта під час перебирання його властивостей, можуть бути як оброблені пізніше, так і пропущені в циклі.

Загалом, під час ітерування краще не додавати, не змінювати й не видаляти властивості з об'єкта, окрім властивості, котра безпосередньо обробляється поточною ітерацією. Немає ніяких гарантій того, що додана властивість буде опрацьована циклом, чи буде змінена властивість оброблена до, чи після модифікації, і чи буде видалена властивість опрацьована до моменту видалення.

Ітерування масиву і цикл for...in

Індекси масиву — це лише перелічувані властивості, які у всьому ідентичні властивостям звичайних об'єктів, окрім того, що їхні імена — це цілі числа. Цикл for...in обробить всі ключі, які є цілими числами, перед початком обробки інших ключів, чітко у напрямку їхнього зростання, що робить поведінку інструкції for...in близькою до звичайного перебирання масиву. Проте, цикл for...in також поверне всі перелічувані властивості, включно з успадкованими й тими, чиї ключі не є цілими числами. На відміну від for...of, for...in використовує перелічування властивостей замість ітератора масиву. У розріджених масивах for...of буде обробляти порожні гнізда, а for...in — ні.

Краще використовувати цикл for з числовим індексом, Array.prototype.forEach() чи цикл for...of, оскільки вони повертатимуть індекс як число, а не як рядок, а також уникатимуть властивостей поза індексом.

Перебирання лише власних властивостей об'єкта

В разі, якщо необхідно розглянути лише ті властивості, які приєднані до самого об'єкта, без урахування його прототипів, можна застосувати один із наступних підходів:

Object.keys поверне список власних перелічуваних властивостей із рядковими ключами, а от Object.getOwnPropertyNames також міститиме неперелічувані властивості.

Багато настанов щодо стилю та лінтерів у JavaScript рекомендують не застосовувати for...in через те, що він перебирає весь ланцюжок прототипів, а це рідко є бажаним. Також його часто плутають із більш вживаним циклом for...of. Найбільш доцільним може бути його використання для потреб зневадження, як простого способу перевірити властивості об'єкта (шляхом виведення їх у консоль, або ж інакшим чином). В ситуаціях, коли об'єкти використовуються як утилітарні пари ключ-значення, for...in дає змогу перевірити, чи зберігає якийсь з таких ключів певне значення.

Приклади

Застосування for...in

Цикл for...in, який наведено нижче, перевіряє всі перелічувані, несимвольні властивості об'єкта, і для кожної друкує рядок з іменем властивості та її значенням.

const 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"

Перебирання власних властивостей об'єкта

Наступна функція демонструє використання методу Object.hasOwn(): успадковані властивості не виводяться.

const 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 (Object.hasOwn(obj, prop)) {
    console.log(`obj.${prop} = ${obj[prop]}`);
  }
}

// Друкує:
// "obj.color = red"

Специфікації

Сумісність із браузерами

desktop mobile server
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet Deno Node.js
for...in
Chrome Full support 1
Edge Full support 12
Firefox Full support 1
Internet Explorer Full support 3
Opera Full support 2
Safari Full support 1
WebView Android Full support 4.4
Chrome Android Full support 18
Firefox for Android Full support 4
Opera Android Full support 10.1
Safari on iOS Full support 1
Samsung Internet Full support 1.0
Deno Full support 1.0
Node.js Full support 0.10.0

Дивіться також