Array.prototype.forEach()

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: http://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: http://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)

Vegeu també

Document Tags and Contributors

 Contributors to this page: enTropy
 Last updated by: enTropy,