Метод array.forEach() перебирає елементи масиву за зростанням, при цьому не змінюючи сам масив. Синтаксис методу forEach():

array.forEach(callback [, thisArgument])

Перший параметр forEach() – це callback функція, котра викликається для кожного елемента масиву. Другий параметр (необов’язковий) – якщо його задано, це значення буде встановлено як this, для кожного виклику callback функції (в іншому випадку це буде undefined).

Практичний приклад роботи forEach():

const letters = ['a', 'b', 'c'];

function printItem(item) {
  console.log(item);
}

letters.forEach(printItem); // a b c

  • в прикладі вище, масив letters містить 3 елементи, а forEach() використовується для виведення на консоль кожної літери
  • printItem – виконує роль callback функції
  • letters.forEach(printItem) – виконує функцію printItem для кожного елемента в letters

Також слід додати, що forEach() пропускає порожні слоти масиву, коли його застосовано до розрідженого масиву (sparse array):

const letters = ['a', , 'c'];
console.log(letters.length); // 3

letters.forEach(function (item) {
  console.log(item);
});

// a c

Індекс елемента ітерації

array.forEach(callback) виконує callback функцію з 3 параметрами: поточний елемент ітерації, індекс та сам екземпляр масиву.

Приклад отримання індексу, для кожного елемента масиву letters:

const letters = ['a', 'b', 'c'];

function printItem(item, index) {
  console.log(`${index}: ${item}`);
}

letters.forEach(printItem);

// 0: a
// 1: b
// 2: c

Доступ до масиву всередині callback функції

Для отримання доступу до масиву під час ітерації, можна використати 3-й параметр callback функції. Наприклад спробуємо додати вивід повідомлення, про останню ітерацію над елементами масиву:

const letters = ['a', 'b', 'c'];

function printItem(item, index, array) {
  console.log(`${index}: ${item}`);
  if (index === array.length - 1) {
    console.log('Last iteration');
  }
}

letters.forEach(printItem);

// 0: a
// 1: b
// 2: c
// Last iteration

3-й параметр функції printItemarray, є масивом, відносно котрого викликається метод forEach().

this всередині callback функції

За допомогою другого параметра методу forEach(), можна встановити посилання this на об’єкт, по якому він буде доступний всередині callback функції:

class Unique {
  constructor(items) {
    this.items = items;
  }

  append(newItems) {
    newItems.forEach(function (newItem) {
      if (!this.items.includes(newItem)) {
        this.items.push(newItem);
      }
    }, this);
  }
}

const uniqueLetters = new Unique(['a']);
console.log(uniqueLetters.items); // [ 'a' ]

uniqueLetters.append(['a', 'b', 'c']);
console.log(uniqueLetters.items); // [ 'a', 'b', 'c' ]

newItems.forEach(function() {}, this) викликається з другим аргументом, котрий вказує на this (тобто поточний екземпляр класу Unique). Завдяки цьому, всередині callback функції для forEach(), забезпечується безпечний доступ до властивості this.items.

Для наведеного вище прикладу, має сенс використовувати стрілочну функцію (arrow function), в якості callback для forEach(). Стрілочна функція зберігає значення this з лексичної області видимості, що дає змогу не використовувати this другим аргументом forEach():

class Unique {
  constructor(items) {
    this.items = items;
  }

  append(newItems) {
    newItems.forEach((newItem) => {
      if (!this.items.includes(newItem)) {
        this.items.push(newItem);
      }
    });
  }
}

const uniqueLetters = new Unique(['a']);
console.log(uniqueLetters.items); // [ 'a' ]

uniqueLetters.append(['a', 'b', 'c']);
console.log(uniqueLetters.items); // [ 'a', 'b', 'c' ]

Використання forEach для ітерації array-like об’єктів

forEach() також може перебирати array-подібні об’єкти, за допомогою непрямого виклику:

const letters = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3,
};

function printItem(item) {
  console.log(item);
}

Array.prototype.forEach.call(letters, printItem); // a b c

В прикладі вище, letters є array-подібним об’єктом (має індексований доступ до властивостей, та властивість length, подібно до масивів). Для перебору елементів letters, слід опосередковано викликати forEach(): Array.prototype.forEach.call(…).

Крім того, можна перетворити array-подібний об’єкт у масив за допомогою Array.from(), після чого виконати ітерацію:

const letters = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3,
};

function printItem(item) {
  console.log(item);
}

Array.from(letters).forEach(printItem); // a b c

Підсумок

Метод array.forEach(callback) є гарним способом перебору всіх елементів масиву. Його першим аргументом є callback функція, котра викликається для кожного елемента масиву з 3-ма аргументами: поточний елемент ітерації, індекс і сам масив.

forEach() є корисним для перебору всіх елементів масиву, без переривання. Слід мати на увазі, що відсутня можливість перервати ітерацію forEach() (окрім як згенерувати помилку для зупинки ітерації, що не є кращою практикою). Зазвичай метод виконує ітерацію над усіма елементами. Якщо ваш випадок вимагає раннього виходу з циклу, кращим варіантом буде класичний for або for…of.