Сводка
Метод forEach()
выполняет указанную функцию один раз для каждого элемента в массиве.
Синтаксис
arr.forEach(callback[, 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()
посетит их; удалённые элементы посещены не будут.
Примечание: Не существует способа остановить или прервать цикл forEach()
. Если это требуется, можно воспользоваться методами Array.prototype.every()
или Array.prototype.some()
. Смотрите примеры ниже.
Метод forEach()
выполняет функцию callback
один раз для каждого элемента массива; в отличие от методов every()
и some()
, он всегда возвращает значение undefined
.
Примеры
Пример: печать содержимого массива
Следующий код выводит каждый элемент массива на новой строке журнала:
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): https://es5.github.io/#x15.4.4.18 // Ссылка (ru): https://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. // Смотрите: https://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' в этой спецификации. |
Стандарт |
Совместимость с браузерами
Возможность | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Базовая поддержка | (Да) | 1.5 (1.8) | 9 | (Да) | (Да) |
Возможность | Android | Chrome для Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Базовая поддержка | (Да) | (Да) | 1.0 (1.8) | (Да) | (Да) | (Да) |