Skip to main content

Як пройти по масиву циклом?

Коротка відповідь

  • Потрібен індекс, контроль кроків, break/continue: класичний for.
  • Потрібні лише значення, читабельність і можливість переривати: for...of.
  • Просто виконати дію для кожного елемента без переривання: forEach.
  • Отримати новий масив/значення: map, filter, reduce, some/every, find.
  • Асинхронний послідовний обхід: for...of + await. Паралельно: Promise.all з map.
  • Не використовуйте for...in для масивів (він для об'єктів, може обходити зайві властивості).

Детальний розбір

1) Індексний for, максимум контролю

Підходить, коли потрібен індекс, крок, ранній вихід, пропуски ітерацій і максимальна продуктивність на гарячих ділянках.

javascript
const arr = [10, 20, 30, 40]; for (let i = 0; i < arr.length; i++) { if (arr[i] === 30) continue; // пропустити 30 if (arr[i] > 35) break; // перервати цикл console.log(i, arr[i]); // індекс і значення }

2) for...of, зручний перебір значень

Простий синтаксис для значень, підтримує break/continue/return з обгортаючої функції. Для індексів використовуйте arr.entries().

javascript
const arr = ['a', 'b', 'c']; for (const v of arr) { if (v === 'b') continue; // пропустити console.log(v); } // Індекс + значення через entries() for (const [i, v] of arr.entries()) { console.log(i, v); }

3) Array.prototype.forEach, без переривання

Виконує функцію для кожного елемента, але не можна зробити break/continue; return завершить лише колбек. Для раннього виходу використовуйте for/for...of.

javascript
const arr = [1, 2, 3]; arr.forEach((value, index) => { // НЕМАЄ способу перервати весь forEach до кінця console.log(index, value); });

4) while / do...while, коли умова первинна

Використовуються, коли ітерації контролюються умовою, а не довжиною масиву (наприклад, читання з черги).

javascript
const queue = [1, 2, 3]; while (queue.length) { const item = queue.shift(); console.log(item); } do { // виконається щонайменше один раз } while (false);

5) for...in, не для масивів

Перебирає перелічувані ключі об'єкта, включно зі успадкованими та рядковими ключами. Для масивів може дати несподіваний порядок і «зайві» властивості.

javascript
const arr = [10, 20]; arr.extra = 42; // додали властивість for (const k in arr) { console.log(k); // '0', '1', 'extra', не те, що очікували } // Замість цього використовуйте for, for...of або методи масиву.

Функціональні методи: map / filter / reduce / some / every / find

Ідеальні, коли потрібен новий масив/значення зі старого. Вони не модифікують вихідний масив (крім рідкісних випадків з мутаціями всередині колбеку).

javascript
const users = [ { id: 1, name: 'Ann', active: true }, { id: 2, name: 'Bob', active: false }, { id: 3, name: 'Cat', active: true }, ]; const activeNames = users .filter(u => u.active) // залишити активних .map(u => u.name); // взяти імена const hasInactive = users.some(u => !u.active); // true/false const allActive = users.every(u => u.active); // true/false const byId = users.reduce((acc, u) => { acc[u.id] = u; // акумулюємо в об'єкт return acc; }, {}); const firstInactive = users.find(u => !u.active); // перший підхожий

Індекс + значення

Якщо потрібен і індекс, і значення, використовуйте arr.entries() з for...of, або другий аргумент колбеку в forEach/map/filter.

javascript
const arr = ['x', 'y', 'z']; for (const [i, v] of arr.entries()) { console.log(i, v); } arr.forEach((v, i) => console.log(i, v));

Переривання й пропуск ітерацій

break/continue працюють з for/for...of/while. У forEach та методах масиву вони недоступні (використовуйте умовні гілки чи інші конструкції).

javascript
const arr = [1, 2, 3, 4, 5]; for (const n of arr) { if (n % 2 === 0) continue; // пропустити парні if (n > 4) break; // зупинитися на 5 console.log(n); }

Асинхронні обходи

Для послідовних асинхронних операцій використовуйте for...of + await. Для паралельного виконання використовуйте map -> Promise.all. Не використовуйте await всередині forEach, він не чекає.

javascript
// Послідовно async function processSequential(urls) { for (const url of urls) { const res = await fetch(url); console.log(url, res.status); } } // Паралельно async function processParallel(urls) { const responses = await Promise.all(urls.map(url => fetch(url))); responses.forEach((res, i) => console.log(urls[i], res.status)); } // Антипатерн: await у forEach async function bad(urls) { urls.forEach(async (url) => { const res = await fetch(url); // не чекає завершення всіх console.log(res.status); }); // Функція завершиться до завершення всіх fetch }

Продуктивність і читабельність: тези

  • На гарячих ділянках класичний for зазвичай трохи швидший, але різниця рідко критична.
  • Обирайте найбільш читабельний варіант, що відповідає задачі (map/filter для перетворень, for...of для простого обходу).
  • Уникайте мутацій масиву в процесі обходу (push/shift на вихідному масиві), якщо це не потрібно.

Шпаргалка вибору

  • Потрібен новий масив зі старого: map/filter/flatMap.
  • Потрібно акумулювати одне значення (сума, об'єкт, карта): reduce.
  • Знайти/перевірити: find/some/every.
  • Простий обхід значень з можливістю break: for...of.
  • Індекс, крок, складні умови, продуктивність: класичний for.
  • Асинхронно послідовно: for...of + await.
  • Асинхронно паралельно: Promise.all + map.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.