This page was translated from English by the community.Learn more and join the MDN Web Docs community.
Array.prototype.forEach()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since июль 2015 г..
МетодforEach() выполняет указанную функцию один раз для каждого элемента в массиве.
In this article
Интерактивный пример
const array1 = ["a", "b", "c"];array1.forEach((element) => console.log(element));// Expected output: "a"// Expected output: "b"// Expected output: "c"Синтаксис
arr.forEach(function callback(currentValue, index, array) { //your iterator}[, thisArg]);Параметры
callbackФункция, которая будет вызвана для каждого элемента массива. Она принимает от одного до трёх аргументов:
currentValueТекущий обрабатываемый элемент в массиве.
indexНеобязательныйИндекс текущего обрабатываемого элемента в массиве.
arrayНеобязательныйМассив, по которому осуществляется проход.
thisArgНеобязательный параметр. Значение, используемое в качестве
thisпри вызове функцииcallback.
Возвращаемое значение
Описание
МетодforEach() выполняет функциюcallback один раз для каждого элемента, находящегося в массиве в порядке возрастания. Она не будет вызвана для удалённых или пропущенных элементов массива. Однако, она будет вызвана для элементов, которые присутствуют в массиве и имеют значениеundefined.
Функцияcallback будет вызвана стремя аргументами:
- значение элемента (value)
- индекс элемента (index)
- массив, по которому осуществляется проход (array)
Если в методforEach() был передан параметрthisArg, при вызовеcallback он будет использоваться в качестве значенияthis. В противном случае, в качестве значенияthis будет использоваться значениеundefined. В конечном итоге, значениеthis, наблюдаемое из функцииcallback, определяется согласнообычным правилам определения.this, видимого из функции
Диапазон элементов, обрабатываемых методомforEach(), устанавливается до первого вызова функцииcallback. Элементы, добавленные в массив после начала выполнения методаforEach(), не будут посещены функциейcallback. Если существующие элементы массива изменятся, значения, переданные в функциюcallback, будут значениями на тот момент времени, когда методforEach() посетит их; удалённые элементы посещены не будут. Если уже посещённые элементы удаляются во время итерации (например, с помощьюshift()), последующие элементы будут пропущены. (Смотри пример ниже)
Примечание:Не существует способа остановить или прервать циклforEach() кроме как выбрасыванием исключения. Если вам необходимо такое поведение, методforEach() неправильный выбор.
Досрочное прекращение может быть достигнуто с:
- Простой цикл
for - Циклы
for...of/for...in Array.prototype.every()Array.prototype.some()Array.prototype.find()Array.prototype.findIndex()
Если нужно протестировать элементы массива на условие и нужно вернуть булево значение, вы можете воспользоваться методамиevery(),some(),find() илиfindIndex().
МетодforEach() выполняет функциюcallback один раз для каждого элемента массива; в отличие от методовevery() иsome(), он всегда возвращает значениеundefined.
Примеры
>Нет операции для неинициализированных значений (разреженные массивы)
const arraySparse = [1, 3, , 7];let numCallbackRuns = 0;arraySparse.forEach((element) => { console.log(element); numCallbackRuns++;});console.log("numCallbackRuns: ", numCallbackRuns);// 1// 3// 7// numCallbackRuns: 3// комментарий: как вы видите пропущенное значение между 3 и 7 не вызывало функцию callback.Конвертируем цикл for в forEach
const items = ["item1", "item2", "item3"];const copy = [];// доfor (let i = 0; i < items.length; i++) { copy.push(items[i]);}// послеitems.forEach(function (item) { copy.push(item);});Печать содержимого массива
Примечание:Для отображения содержимого массива в консоли вы можете использоватьconsole.table(), который выводит отформатированную версию массива.
Следующий пример иллюстрирует альтернативный подход, использующийforEach().
Следующий код выводит каждый элемент массива на новой строке журнала:
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ИспользованиеthisArg
Следующий (надуманный) пример обновляет свойства объекта, когда перебирает записи массива:
function Counter() { this.sum = 0; this.count = 0;}Counter.prototype.add = function (array) { array.forEach((entry) => { this.sum += entry; ++this.count; }, this); // ^---- Note};const obj = new Counter();obj.add([2, 5, 9]);obj.count;// 3obj.sum;// 16Поскольку вforEach() передан параметрthisArg (this), он затем передаётся вcallback при каждом вызове. И callback использует его в качестве собственного значенияthis.
Примечание:Если при передаче callback функции используетсявыражение стрелочной функции, параметрthisArg может быть опущен, так как все стрелочные функции лексически привязываются к значениюthis.
Прерывание цикла
Следующий код использует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: falseres = 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Модификация массива во время итерации
В следующем примере в лог выводится"one","two","four".
При достижении записи, содержащей значение'two', первая запись всего массива удаляется, в результате чего все оставшиеся записи перемещаются на одну позицию вверх. Поскольку элемент'four' теперь находится на более ранней позиции в массиве,'three' будет пропущен.
forEach() не делает копию массива перед итерацией.
let words = ["one", "two", "three", "four"];words.forEach((word) => { console.log(word); if (word === "two") { words.shift(); }});// one// two// fourВыравнивание (уплощение) массива
Следующий пример приведён только для целей обучения. Если вы хотите выравнять массив с помощью встроенных методов, вы можете использоватьArray.prototype.flat()
function flatten(arr) { const result = []; arr.forEach((i) => { if (Array.isArray(i)) { result.push(...flatten(i)); } else { result.push(i); } }); return result;}// Usageconst nested = [1, 2, 3, [4, 5, [6, 7], 8, 9]];flatten(nested); // [1, 2, 3, 4, 5, 6, 7, 8, 9]Полифил
Метод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.18if (!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. };}Спецификации
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-array.prototype.foreach> |