La méthode forEach()
permet d'exécuter une fonction donnée sur chaque élément du tableau.
Syntaxe
arr.forEach(callback[, thisArg])
Paramètres
callback
- La fonction à utiliser pour chaque élément du tableau. Elle prend en compte trois arguments :
valeurCourante
- L'élément du tableau en cours de traitement.
index
- L'indice de l'élément du tableau en cours de traitement.
array
- Le tableau sur lequel la méthode
forEach
est appliquée.
thisArg
Facultatif- Paramètre optionnel. La valeur à utiliser pour
this
lors de l'exécution decallback
.
Valeur de retour
Description
forEach()
exécute la fonction callback
une fois pour chaque élément du tableau, dans l'ordre croissant des indices. Cette fonction n'est pas appelée pour les indices pour lesquels les éléments ont été supprimés ou qui n'ont pas été définis. Attention, en revanche elle est appelée pour les éléments qui sont présents et qui valent undefined
.
callback
est appelé avec trois arguments :
- la valeur de l'élément
- l'index de l'élément
- le tableau utilisé
Si un paramètre thisArg
est fourni à la méthode forEach
, il sera utilisé en tant que valeur this
pour chaque appel de callback
. Sinon, ce sera la valeur undefined
qui sera utilisée comme valeur this
. La valeur this
prise en compte par la fonction callback
est déterminée selon les règles usuelles pour déterminer la valeur de this
utilisée dans une fonction.
L'ensemble des éléments traités par forEach
est défini avant le premier appel à callback
. Les éléments ajoutés au tableau après que l'appel à forEach
ait commencé ne seront pas visités par callback
. Si des éléments déjà présents dans le tableau sont modifiés, leur valeur telle qu'elle est passée au callback
sera la valeur au moment du passage du forEach
; les éléments supprimés ne sont pas parcourus.
forEach()
exécute la fonction callback
une fois pour chaque élément. À la différence de map()
ou de reduce()
il renvoie toujours la valeur undefined
et ne peut donc pas être « enchaîné ». Généralement, l'effet voulu est de déclencher des effets de bord en fin de chaîne.
forEach
. La solution consiste à utiliser Array.prototype.every
ou Array.prototype.some
. Voir les exemples ci-après. Si elles sont disponibles, les nouvelles méthodes find()
ou findIndex()
peuvent être utilisées afin d'utiliser des critères de terminaison.forEach
exécute la fonction callback
une fois pour chaque élément ; contrairement à every
et
, cette méthode renvoie toujours some
undefined
et ne peut pas être enchaînée.
Exemples
Afficher le contenu d'un tableau
Le code suivant affiche une ligne pour chaque élément du tableau:
function logArrayElements(element, index, array) { console.log("a[" + index + "] = " + element); } [2, 5, , 9].forEach(logArrayElements); // logs: // a[0] = 2 // a[1] = 5 // a[3] = 9
Utiliser l'argument pour this
Dans l'exemple qui suit, on met à jour les propriétés d'un objet à partir des éléments d'un tableau :
function Compteur() { this.somme = 0; this.compte = 0; } Compteur.prototype.ajouter = function(tableau) { tableau.forEach(function(element) { this.somme += element; ++this.compte; }, this); // ^---- On a ajouté l'argument this ici. }; var obj = new Compteur(); obj.ajouter([2, 5, 9]); console.log(obj.compte); // 3 console.log(obj.somme); // 16
Note : Le paramètre pour this
est passé à la méthode forEach()
, à chaque appel du callback, celui-ci sera utilisé comme valeur pour this
.
Note : Si la fonction passée en argument est une fonction fléchée, il n'est pas nécessaire d'ajouter le paramètre this
car les fonctions fléchées utilisent le this
fourni par le contexte lexical.
Stopper une boucle
Le code qui suit utilise la méthode Array.prototype.every
pour afficher le contenu d'un tableau et s'arrêter lorsqu'il atteint une valeur supérieure à SEUIL_MAX
.
var SEUIL_MAX = 12; var v = [5, 2, 16, 4, 3, 18, 20]; var res; res = v.every(function(element, index, array) { console.log('élément :', element); if (element >= SEUIL_MAX) { return false; } return true; }); console.log('res:', res); // affiche : // élément : 5 // élément : 2 // élément : 16 // res : false res = v.some(function(element, index, array) { console.log('élément:', element); if (element >= SEUIL_MAX) { return true; } return false; }); console.log('res:', res); // affiche : // élément : 5 // élément : 2 // élément : 16 // res: true
Une fonction de copie d'objet
Le code qui suit permet de créer une copie d'un objet donné. Il existe différentes façons pour créer une copie d'un objet. L'exemple suivant illustre une de ces façons afin d'expliquer le fonctionnement d'Array.prototype.forEach
et d'utiliser les fonctions ECMAScript 5 Object.*
.
function copie(obj) { var copie = Object.create(Object.getPrototypeOf(obj)); var propNames = Object.getOwnPropertyNames(obj); propNames.forEach(function(nom) { var desc = Object.getOwnPropertyDescriptor(obj, nom); Object.defineProperty(copie, nom, desc); }); return copie; } var obj1 = { a: 1, b: 2 }; var obj2 = copie(obj1); // obj2 ressemble désormais à obj1
Attention aux modifications en cours
Dans l'exemple qui suit, on utilise un tableau qui contient quatre élément : "un"
, "deux"
, "trois"
, "quatre"
. Lorsque le parcours du tableau arrive à l'élément "deux"
, on décale le tableau d'un cran vers les premiers éléments. Aussi, l'élément "quatre"
est décalé à la place de "trois"
et "trois"
est déplacé à la place de "deux"
. Pour cette raison, lorsque forEach
poursuit son parcours, elle saute la valeur "trois". Autrement dit, forEach
n'utilise pas une copie du tableau au moment où elle est appelée, elle manipule le tableau directement.
var mots = ["un", "deux", "trois", "quatre"]; mots.forEach(function(mot) { console.log(mot); if (mot === "deux") { mots.shift(); } }); // un // deux // quatre
Prothèse d'émulation (polyfill)
forEach
fut ajouté avec ECMAScript 5 (la cinquième édition du standard ECMA-262). Certains environnements basés sur d'anciens standards peuvent ne pas disposer de cette méthode. Pour parer à ce cas, on peut émuler la fonction en utilisant le fragment de code ci-dessous. L'algorithme utilisé dans ce code correspond exactement à celui défini par ECMAScript 5, sous réserve que Object
et TypeError
n'aient pas été modifiés et que callback.call
corresponde à la valeur originale de Function.prototype.call
.
// ECMA-262, Edition 5, 15.4.4.18 // Référence: 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 vaut null ou n est pas défini'); } // 1. Soit O le résultat de l'appel à ToObject // auquel on a passé |this| en argument. var O = Object(this); // 2. Soit lenValue le résultat de l'appel de la méthode // interne Get sur O avec l'argument "length". // 3. Soit len la valeur ToUint32(lenValue). var len = O.length >>> 0; // 4. Si IsCallable(callback) est false, on lève une TypeError. // Voir : https://es5.github.com/#x9.11 if (typeof callback !== "function") { throw new TypeError(callback + ' n est pas une fonction'); } // 5. Si thisArg a été fourni, soit T ce thisArg ; // sinon soit T égal à undefined. if (arguments.length > 1) { T = thisArg; } // 6. Soit k égal à 0 k = 0; // 7. On répète tant que k < len while (k < len) { var kValue; // a. Soit Pk égal ToString(k). // (implicite pour l'opérande gauche de in) // b. Soit kPresent le résultat de l'appel de la // méthode interne HasProperty de O avec l'argument Pk. // Cette étape peut être combinée avec c // c. Si kPresent vaut true, alors if (k in O) { // i. Soit kValue le résultat de l'appel de la // méthode interne Get de O avec l'argument Pk. kValue = O[k]; // ii. On appelle la méthode interne Call de callback // avec T comme valeur this et la liste des arguments // qui contient kValue, k, et O. callback.call(T, kValue, k, O); } // d. On augmente k de 1. k++; } // 8. on renvoie undefined }; }
Spécifications
Spécification | État | Commentaires |
---|---|---|
ECMAScript 5.1 (ECMA-262) La définition de 'Array.prototype.forEach' dans cette spécification. |
Standard | Définition initiale. Implémentée avec JavaScript 1.6. |
ECMAScript 2015 (6th Edition, ECMA-262) La définition de 'Array.prototype.forEach' dans cette spécification. |
Standard | |
ECMAScript 2017 Draft (ECMA-262) La définition de 'Array.prototype.forEach' dans cette spécification. |
Projet |
Compatibilité des navigateurs
Fonctionnalité | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Support simple | (Oui) | 1.5 (1.8) | 9 | (Oui) | (Oui) |
Fonctionnalité | Android | Chrome pour Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Support simple | (Oui) | (Oui) | 1.0 (1.8) | (Oui) | (Oui) | (Oui) |