El mètode forEach()
executa la funció rebuda un cop per cada element de l'array.
Sintaxi
arr.forEach(callback[, thisArg])
Paràmetres
callback
- Funció a executar per a cada element. Aquesta funció rebrà tres paràmetres:
valor
- L'element que s'està processant ara mateix a l'array.
posició
- La posició que l'element actual ocupa dins l'array.
array
- L'array al qual el mètode
forEach
s'aplica.
thisArg
- Opcional. Valor que s'utilitzarà com a
this
a l'hora d'executar la funciócallback
.
Descripció
forEach()
executa la funció callback
rebuda com a argument un cop per cada element present a l'array, en ordre ascendent. No es cridarà la funció per a elements que s'hagin eliminat o que no hagin rebut cap valor (és a dir, arrays disperses).
S'invocarà callback
amb els tres arguments següents:
- el valor de l'element
- la posició de l'element
- L'array que s'està recorrent
Si es proporciona el paràmetre thisArg
a forEach()
, aquest es passarà a callback
quan es cridi, i es podrà accedir a ell mitjançant la paraula clau this
. En el cas que no es proporcioni el paràmetre this
rebrà el valor undefined
. El valor de this
que serà observable per callback
es determina d'acord a les regles usuals per a determinar el valor de this
que una funció veu.
El rang dels elements processats per forEach()
és determinat abans de la primera invocació de callback
. Els elements que s'afegeixin a l'array després de la crida a forEach()
no seran visitats per la funció callback
. En el cas que es canviï el valor dels elements de l'array el valor que es passarà a callback
serà el valor que tingui l'element en el moment que es visita. Els elements que s'han eliminat abans de ser visitats no es visitaran.
forEach()
executa la funció callback
un cop per cada element de l'array; a diferència de map()
i reduce()
, sempre retorna el valor undefined
i no es pot encadenar. El cas d'ús típic és per executar efectes secundaris al final de la cadena.
Nota: L'única forma d'aturar un bucle forEach()
és llençar una excepció. Si es requereix aquesta funcionalitat llavors el mètode .forEach()
és l'eina incorrecta i es recomana utilitzar un bucle normal. Si el que es pretén és validar els elements d'un array contra un predicat i es requereix retornar un valor booleà, es recomana utilitzar la funció every()
o bé some()
.
Exemples
Imprimir el contingut d'un array
El codi següent mostra una línia per a cada element de l'array:
function logArrayElements(element, index, array) { console.log('a[' + index + '] = ' + element); } // Cal destacar l'omissió, no hi ha cap element a la posició 2 així que aquesta no es visita [2, 5, , 9].forEach(logArrayElements); // Mostra: // a[0] = 2 // a[1] = 5 // a[3] = 9
Una funció per a copiar objectes
El codi següent crea una copia de l'objecte donat. Hi ha diverses formes de crear una copia d'un objecte, la forma següent és simplement una d'elles i es presenta per a explicar com funciona Array.prototype.forEach()
tot utilitzant les funcions de meta-propietats de l'ECMAScript 5 a Object.*
function copy(obj) { var copy = Object.create(Object.getPrototypeOf(obj)); var propNames = Object.getOwnPropertyNames(obj); propNames.forEach(function(name) { var desc = Object.getOwnPropertyDescriptor(obj, name); Object.defineProperty(copy, name, desc); }); return copy; } var obj1 = { a: 1, b: 2 }; var obj2 = copy(obj1); // obj2 looks like o1 now
Polyfill
forEach()
va ser afegida l'standard ECMA-262 en la cinquena edició; per aquest motiu aquesta funció pot no estar present en altres implementacions de l'standard. Es pot solventar aquest problema inserint el codi següent a l'inici dels vostres scripts. Això permetrà l'ús de forEach()
en implementacions que no el suportin de forma nativa. Aquest algoritme és el mateix que l'especificat a l'ECMA-262, cinquena edició, si assumim que Object
i TypeError
tenen els seus valors originals i que callback.call
es resol com al valor original de Function.prototype.call()
.
// Production steps of ECMA-262, Edition 5, 15.4.4.18 // Reference: https://es5.github.io/#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. Assignem a O el resultat de cridar ToObject tot passant-li el valor de |this| com a argument. var O = Object(this); // 2. lenValue representa el resultat de cridar el mètode intern Get de O amb l'argument "length". // 3. Assignem a len el valor ToUint32(lenValue). var len = O.length >>> 0; // 4. Si IsCallable(callback) és false, llençem una excepció TypeError. // Vegeu: https://es5.github.com/#x9.11 if (typeof callback !== "function") { throw new TypeError(callback + ' no és una funció'); } // 5. Si s'ha passat thisArg com a aragument, assignem el seu valor a la variable T, en qualsevol altre cas deixem T com a undefined. if (arguments.length > 1) { T = thisArg; } // 6. Assignem 0 a la variable k k = 0; // 7. Repetir, mentre k < len while (k < len) { var kValue; // a. Assignem ToString(k) a Pk. // Aquest comportament és implícit per a operands al cantó esquerra (de l'anglés LHS o Left-Hand-Side) de l'operador "in"This is implicit for LHS operands of the in operator // b. Assignem el resultat de cridar el mètode intern HasProperty de O amb l'argument Pk a la variable kPresent // Podem combinar aquest pas amb c // c. Si kPresent és true, llavors... if (k in O) { // i. Assignem a kValue el resultat de cridar el mètode intern Get de l'objecte O amb l'argument Pk. kValue = O[k]; // ii. Cridem el mètode intern "call" del callback tot passant-li T com a valor de "this" // així com una llista d'arguments que conté kValue, k i 0 callback.call(T, kValue, k, O); } // d. Incrementem el valor de k en 1. k++; } // 8. retornem undefined }; }
Especificacions
Especificació | Estat | Comentaris |
---|---|---|
ECMAScript 5.1 (ECMA-262) The definition of 'Array.prototype.forEach' in that specification. |
Standard | Definició inicial. Implementat a JavaScript 1.6. |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Array.prototype.forEach' in that specification. |
Standard |
Compatibilitat amb navegadors
Característica | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Suport bàsic | (Yes) | 1.5 (1.8) | 9 | (Yes) | (Yes) |
Característica | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Suport bàsic | (Yes) | (Yes) | 1.0 (1.8) | (Yes) | (Yes) | (Yes) |