Метод forEach() выполняет указанную функцию один раз для каждого элемента в массиве.

Синтаксис

arr.forEach(function callback(currentValue, index, array) {
    //your iterator
}[, thisArg]);

Параметры

callback
Функция, которая будет вызвана для каждого элемента массива; в нее будет передано три аргумента:
currentValue
Текущий обрабатываемый элемент в массиве.
indexНеобязательный
Индекс текущего обрабатываемого элемента в массиве.
arrayНеобязательный
Массив, по которому осуществляется проход.
thisArg
Необязательный параметр. Значение, используемое в качестве this при вызове функции callback.

Возвращаемое значение

undefined.

Описание

Метод forEach() выполняет функцию callback один раз для каждого элемента, находящегося в массиве в порядке возрастания. Она не будет вызвана для удалённых или пропущенных элементов массива. Однако, она будет вызвана для элементов, которые присутствуют в массиве и имеют значение undefined.

Функция callback будет вызвана с тремя аргументами:

  • значение элемента (value)
  • индекс элемента (index)
  • массив, по которому осуществляется проход (array)

Если в метод forEach() был передан параметр thisArg, при вызове callback он будет использоваться в качестве значения this. В противном случае, в качестве значения this будет использоваться значение undefined. В конечном итоге, значение this, наблюдаемое из функции callback, определяется согласно обычным правилам определения this, видимого из функции.

Диапазон элементов, обрабатываемых методом forEach(), устанавливается до первого вызова функции callback. Элементы, добавленные в массив после начала выполнения метода forEach(), не будут посещены функцией callback. Если существующие элементы массива изменятся, значения, переданные в функцию callback, будут значениями на тот момент времени, когда метод forEach() посетит их; удалённые элементы посещены не будут.

Примечание: Не существует способа остановить или прервать цикл forEach() кроме как выбрасыванием исключения. Если это требуется, метод forEach() неправильный выбор. Используйте обычные циклы. Если нужно протестировать элементы массива на условие и нужно вернуть булевое значение, вы должны воспользоваться методами Array.prototype.every() или Array.prototype.some().

Метод forEach() выполняет функцию callback один раз для каждого элемента массива; в отличие от методов every() и some(), он всегда возвращает значение undefined.

Примеры

Конвертируем for в forEach

До

const items = ['item1', 'item2', 'item3'];
const copy = [];

for (let i=0; i<items.length; i++) {
  copy.push(items[i])
}

после

const items = ['item1', 'item2', 'item3'];
const copy = [];

items.forEach(function(item){
  copy.push(item)
});

Пример: печать содержимого массива

Следующий код выводит каждый элемент массива на новой строке журнала:

function logArrayElements(element, index, array) {
  console.log('a[' + index + '] = ' + element);
}

// Обратите внимание на пропуск по индексу 2, там нет элемента, поэтому он не посещается
[2, 5, , 9].forEach(logArrayElements);
// логи:
// a[0] = 2
// a[1] = 5
// a[3] = 9

Пример: прерывание цикла

Следующий код использует Array.prototype.every() для логирования содержимого массива и останавливается при превышении значением заданного порогового значения THRESHOLD.

var THRESHOLD = 12;
var v = [5, 2, 16, 4, 3, 18, 20];
var res;

res = v.every(function(element, index, array) {
  console.log('element:', element);
  if (element >= THRESHOLD) {
    return false;
  }

  return true;
});
console.log('res:', res);
// логи:
// element: 5
// element: 2
// element: 16
// res: false

res = v.some(function(element, index, array) {
  console.log('element:', element);
  if (element >= THRESHOLD) {
    return true;
  }

  return false;
});
console.log('res:', res);
// логи:
// element: 5
// element: 2
// element: 16
// res: true

Пример: функция копирования объекта

Следующий код создаёт копию переданного объекта. Существует несколько способов создания копии объекта, и это один из них. Он позволяет понять, каким образом работает Array.prototype.forEach(), используя функции мета-свойств Object.* из ECMAScript 5.

function copy(o) {
  var copy = Object.create(Object.getPrototypeOf(o));
  var propNames = Object.getOwnPropertyNames(o);

  propNames.forEach(function(name) {
    var desc = Object.getOwnPropertyDescriptor(o, name);
    Object.defineProperty(copy, name, desc);
  });

  return copy;
}

var o1 = { a: 1, b: 2 };
var o2 = copy(o1); // теперь o2 выглядит также, как и o1

Полифилл

Метод forEach() был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать forEach() в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 5-го издания; он предполагает, что Object и TypeError имеют свои первоначальные значения и что callback.call вычисляется в оригинальное значение Function.prototype.call().

// Шаги алгоритма ECMA-262, 5-е издание, 15.4.4.18
// Ссылка (en): http://es5.github.io/#x15.4.4.18
// Ссылка (ru): http://es5.javascript.ru/x15.4.html#x15.4.4.18
if (!Array.prototype.forEach) {

  Array.prototype.forEach = function (callback, thisArg) {

    var T, k;

    if (this == null) {
      throw new TypeError(' this is null or not defined');
    }

    // 1. Положим O равным результату вызова ToObject passing the |this| value as the argument.
    var O = Object(this);

    // 2. Положим lenValue равным результату вызова внутреннего метода Get объекта O с аргументом "length".
    // 3. Положим len равным ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. Если IsCallable(callback) равен false, выкинем исключение TypeError.
    // Смотрите: http://es5.github.com/#x9.11
    if (typeof callback !== 'function') {
        throw new TypeError(callback + ' is not a function');
    }

    // 5. Если thisArg присутствует, положим T равным thisArg; иначе положим T равным undefined.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. Положим k равным 0
    k = 0;

    // 7. Пока k < len, будем повторять
    while (k < len) {

      var kValue;

      // a. Положим Pk равным ToString(k).
      //   Это неявное преобразование для левостороннего операнда в операторе in
      // b. Положим kPresent равным результату вызова внутреннего метода HasProperty объекта O с аргументом Pk.
      //   Этот шаг может быть объединён с шагом c
      // c. Если kPresent равен true, то
      if (k in O) {

        // i. Положим kValue равным результату вызова внутреннего метода Get объекта O с аргументом Pk.
        kValue = O[k];

        // ii. Вызовем внутренний метод Call функции callback с объектом T в качестве значения this и
        // списком аргументов, содержащим kValue, k и O.
        callback.call(T, kValue, k, O);
      }
      // d. Увеличим k на 1.
      k++;
    }
    // 8. Вернём undefined.
  };
}

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

Спецификация Статус Комментарии
ECMAScript 5.1 (ECMA-262)
Определение 'Array.prototype.forEach' в этой спецификации.
Стандарт Изначальное определение. Реализована в JavaScript 1.6.
ECMAScript 2015 (6th Edition, ECMA-262)
Определение 'Array.prototype.forEach' в этой спецификации.
Стандарт  
ECMAScript Latest Draft (ECMA-262)
Определение 'Array.prototype.forEach' в этой спецификации.
Черновик  

Совместимость с браузерами

ВозможностьChromeEdgeFirefoxInternet ExplorerOperaSafari
Базовая поддержка Да Да1.59 Да Да
ВозможностьAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Базовая поддержка Да Да Да4 Да Да Да

Смотрите также

Метки документа и участники

 Внесли вклад в эту страницу: nikolai-shabalin, JorJeG, paulvoloschuk, kusonka, Mingun, Ajooluz, teoli, dunmaksim, IgorKlopov, ipetropolsky, John Wehin
 Обновлялась последний раз: nikolai-shabalin,