Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Види циклів у JS». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)**У JavaScript є три оператори циклу з лічильником або умовою (`for`, `while`, `do...while`) і два оператори перебору (`for...in` для ключів об’єкта, `for...of` для ітерованих значень), а поруч із ними працюють методи масивів на зразок `forEach`.** `for` беруть, коли кількість ітерацій відома; `while` беруть, коли ні; `do...while` гарантує хоча б один прохід; `for...of` перебирає значення масивів, рядків, `Set` і `Map`, а `for...in` перебирає перелічувані ключі об’єкта, включно з успадкованими. ```javascript for (const value of [10, 20, 30]) console.log(value); // 10, 20, 30 for (const key in { a: 1, b: 2 }) console.log(key); // a, b ``` **Ключове:** оператори `for`, `while`, `do...while`, `for...of` і `for...in` підтримують `break` і `continue`, а метод `forEach` їх не підтримує, тому для дострокового виходу потрібен саме цикл, а не метод.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення**У JavaScript цикли діляться на оператори з умовою (`for`, `while`, `do...while`) та оператори перебору (`for...in`, `for...of`), до яких додаються методи масивів на зразок `forEach`.** Різниця між ними в тому, що саме керує повтореннями: лічильник, умова, ключі об’єкта чи ітератор колекції. ## Теорія ### TL;DR - `for` це класичний цикл, коли кількість ітерацій відома заздалегідь. - `while` це цикл з передумовою: тіло може не виконатися жодного разу. - `do...while` це цикл з післяумовою: тіло гарантовано виконається хоча б один раз. - `for...in` перебирає перелічувані ключі об’єкта, включно з успадкованими, і не гарантує порядок. - `for...of` перебирає значення ітерованих об’єктів: масивів, рядків, `Set`, `Map`, `arguments`. - `forEach` це не оператор, а метод масиву; у ньому не працюють `break` і `continue`. ### Швидкий приклад ```javascript const numbers = [10, 20, 30]; for (let i = 0; i < numbers.length; i++) console.log(numbers[i]); // за індексом for (const value of numbers) console.log(value); // за значенням numbers.forEach((value, index) => console.log(index, value)); // метод масиву ``` ### Цикли з лічильником та умовою #### 1. `for`, класичний цикл Використовується, коли заздалегідь відома кількість ітерацій. ```javascript for (let i = 0; i < 5; i++) { console.log(i); } ``` Результат: ```text 0 1 2 3 4 ``` Структура: ```javascript for (ініціалізація; умова; крок) { // тіло циклу } ``` - `ініціалізація` виконується один раз на початку; - `умова` перевіряється перед кожною ітерацією; - `крок` виконується після кожної ітерації. #### 2. `while`, цикл з передумовою Виконується, доки умова істинна (`true`). ```javascript let i = 0; while (i < 5) { console.log(i); i++; } ``` Використовується, коли кількість ітерацій невідома заздалегідь, наприклад доки черга не порожня або доки сервер не віддав останню сторінку. #### 3. `do...while`, цикл з післяумовою Гарантовано виконається хоча б один раз, бо умова перевіряється вже після тіла. ```javascript let i = 5; do { console.log(i); i++; } while (i < 5); ``` Результат: ```text 5 ``` Спочатку виконується тіло циклу, і лише потім перевіряється умова. ### Оператори перебору #### 4. `for...in`, перебір ключів об’єкта Використовується для проходу по властивостях об’єкта. ```javascript const user = { name: 'Tim', age: 25, city: 'Kyiv' }; for (const key in user) { console.log(key, ':', user[key]); } ``` Результат: ```text name : Tim age : 25 city : Kyiv ``` Особливості: - перебирає всі перелічувані властивості, включно з успадкованими через прототип; - не гарантує порядку (цілочисельні ключі йдуть першими за зростанням); - краще не використовувати для масивів: ключі приходять рядками (`'0'`, `'1'`), а разом із ними можуть прийти й сторонні властивості. #### 5. `for...of`, перебір ітерованих об’єктів Ідеальний для масивів, рядків, `Set`, `Map` та інших ітерованих структур. ```javascript const numbers = [10, 20, 30]; for (const num of numbers) { console.log(num); } ``` Результат: ```text 10 20 30 ``` Працює і з рядком: ```javascript for (const char of 'JS') { console.log(char); } ``` На відміну від `for...in`, він перебирає значення, а не ключі. Якщо потрібен і індекс, беруть `for (const [i, value] of arr.entries())`. ### 6. Метод `forEach()` Це не оператор, а метод масиву, але виконує ту саму задачу: перебір. ```javascript const arr = ['a', 'b', 'c']; arr.forEach((value, index) => { console.log(index, value); }); ``` Результат: ```text 0 a 1 b 2 c ``` Особливості: - не можна використати `break` або `continue`, а `return` усередині колбека лише завершує поточну ітерацію; - зручний для перебору без дострокового виходу; - пропускає «дірки» у розріджених масивах; - поруч із ним стоять `map`, `filter`, `reduce`, `some`, `every`, які повертають результат, тоді як `forEach` завжди повертає `undefined`. ### Порівняльна таблиця | Цикл | Що перебирає | Коли брати | `break` / `continue` | | --- | --- | --- | --- | | `for` | індекси, лічильник | кількість ітерацій відома | так | | `while` | нічого, лише умова | кількість ітерацій невідома | так | | `do...while` | нічого, лише умова | треба хоча б один прохід | так | | `for...in` | перелічувані ключі об’єкта | обхід властивостей об’єкта | так | | `for...of` | значення ітерованого об’єкта | масиви, рядки, `Set`, `Map` | так | | `forEach` | елементи масиву | простий перебір без виходу | ні | ### Типові помилки - Використовувати `for...in` для масивів: отримаєте рядкові ключі та ризик зачепити успадковані властивості. Для масивів беріть `for...of` або звичайний `for`. - Чекати, що `break` зупинить `forEach`. Він не зупиняє; якщо потрібен достроковий вихід, візьміть `for...of`, `some` або `find`. - Забути змінити лічильник у `while` і отримати нескінченний цикл. - Плутати `do...while` і `while`: перший завжди виконує тіло хоча б раз, навіть коли умова хибна від початку. - Оголошувати лічильник через `var` у циклі з асинхронним колбеком: усі колбеки побачать одне й те саме кінцеве значення, бо `var` не має блокової області видимості. Рятує `let`. - Викликати `await` усередині `forEach`: метод не чекає на проміси, тому потрібен `for...of` з `await` або `Promise.all`.Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.