for...in

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

Синтаксис

for (variable in object)
  statement
variable
Нове ім'я властивості призначається параметру variable на кожній ітерації.
object
Об'єкт, чиї не символьні перелічувані властивості перебираються.

Опис

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

Видалені, додані або модифіковані властивості

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

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

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

Перебір масиву та for...in

Заувага: цикл for...in не слід використовувати для перебору масиву, де порядок індексів є важливим.

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

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

Перебір лише особистих властивостей

Якщо ви бажаєте розглядати властивості, притаманні лише самому об'єкту, а не його прототипам, скористайтесь getOwnPropertyNames() або виконайте перевірку hasOwnProperty() (також можна використати propertyIsEnumerable()). Альтернативно, якщо ви певні, що не буде зовнішнього втручання у код, ви можете розширити вбудовані прототипи методом перевірки.

Навіщо використовувати for...in?

Враховуючи, що цикл 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"

Наступна функція ілюструє використання 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"

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

Специфікація Статус Коментар
ECMAScript Latest Draft (ECMA-262)
The definition of 'for...in statement' in that specification.
Draft
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'for...in statement' in that specification.
Standard
ECMAScript 5.1 (ECMA-262)
The definition of 'for...in statement' in that specification.
Standard
ECMAScript 3rd Edition (ECMA-262)
The definition of 'for...in statement' in that specification.
Standard
ECMAScript 1st Edition (ECMA-262)
The definition of 'for...in statement' in that specification.
Standard Початкове визначення.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
for...inChrome Full support 49Edge Full support 12Firefox Full support 1IE Full support 6Opera Full support 36Safari Full support YesWebView Android Full support 49Chrome Android Full support 49Firefox Android Full support 4Opera Android Full support 36Safari iOS Full support YesSamsung Internet Android Full support 5.0nodejs Full support Yes

Legend

Full support  
Full support

Сумісність: Ініціалізація лічильника у строгому режимі

До 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") у строгому режимі (bug 748550 та bug 1164741).

Інші рушії, такі як v8 (Chrome), Chakra (IE/Edge) та JSC (WebKit/Safari), також проводять дослідження щодо прибирання цієї нестандартної поведінки.

Див. також