Il metodo forEach()
esegue una funzione fornita una volta per ogni elemento dell'array.
The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.
Sintassi
arr.forEach(callback(currentValue [, index [, array]])[, thisArg]);
Parametri
callback
- Funzione da eseguire per ciascun elemento, prendendo tre argomenti:
-
currentValue
- L'elemento corrente in elaborazione nell'array.
index
Optional- L'indice dell'elemento corrente in elaborazione nell'array.
array
Optional- L'array a cui viene applicato
forEach()
.
thisArg
Optional- Valore da utilizzare come
this
quando si eseguecallback
.
Descrizione
forEach()
esegue il callback
fornito una volta per ciascun elemento presente nell'array in ordine crescente. Non è invocato per le proprietà dell'indice che sono state eliminate o non inizializzate (ad esempio su array sparsi).
callback
viene invocato con tre argomenti:
- il valore dell'elemento
- l'indice dell'elemento
- l'array che deve essere iterato
Se viene fornito il parametro thisArg
a forEach()
, verrà utilizzato come valore this
del callback. Altrimenti, il valore undefined
sarà usato come valore this
. Il valore this
alla fine osservabile da callback
è determinato secondo le consuete regole per determinare il this
visto da una funzione.
L'intervallo di elementi elaborati da forEach()
viene impostato prima della prima chiamata del callback
. Gli elementi aggiunti all'array dopo che la chiamata forEach()
inizia non saranno calcolati da callback
. Se i valori degli elementi esistenti dell'array vengono modificati, il valore passato a callback
sarà il valore al momento in cui forEach()
li visita; gli elementi che vengono cancellati prima di essere visitati non vengono visitati. Se gli elementi già visitati vengono rimossi (ad esempio usando shift()
) durante l'iterazione, gli elementi successivi verranno saltati - vedi l'esempio sotto.
forEach()
esegue la funzione callback
una volta per ogni elemento dell'array; a differenza di map()
o reduce()
restituisce sempre undefined
e non è concatenabile. Il tipico caso d'uso è eseguire effetti collaterali alla fine del chain.
forEach()
non muta l'array su cui è chiamato (sebbene callback
, se invocato, possa farlo).
Non c'è modo di fermare o interrompere un loop forEach()
se non lanciando un'eccezione. Se hai bisogno di un simile comportamento, il metodo forEach()
è lo strumento sbagliato.
La risoluzione anticipata può essere eseguita con:
- Un loop semplice
- Un loop for...of
Array.prototype.every()
Array.prototype.some()
Array.prototype.find()
Array.prototype.findIndex()
Gli altri metodi per array: Array.prototype.every()
, Array.prototype.some()
, Array.prototype.find()
, e Array.prototype.findIndex()
testano gli elementi dell'array con un predicato restituendo un valore di verità per determinare se è necessaria un'ulteriore iterazione.
Esempi
Convertire un loop for in forEach
const items = ['item1', 'item2', 'item3'];
const copy = [];
// prima
for (let i=0; i<items.length; i++) {
copy.push(items[i]);
}
// dopo
items.forEach(function(item) {
copy.push(item);
});
Stampa del contenuto di un array
Note: Per visualizzare il contenuto di un array nella console, puoi utilizzare console.table()
che stamperà una versione formattata dell'array. L'esempio seguente illustra un altro modo per farlo, usando forEach()
.
Il seguente codice logga una linea per ogni elemento in un array:
function logArrayElements(element, index, array) {
console.log('a[' + index + '] = ' + element);
}
// Nota che l'indice 2 viene saltato poiché non vi è alcun elemento
// in quella posizione nell'array.
[2, 5, , 9].forEach(logArrayElements);
// logga:
// a[0] = 2
// a[1] = 5
// a[3] = 9
Usare thisArg
Il seguente esempio (inventato) aggiorna le proprietà di un oggetto da ciascuna voce dell'array:
function Counter() {
this.sum = 0;
this.count = 0;
}
Counter.prototype.add = function(array) {
array.forEach(function(entry) {
this.sum += entry;
++this.count;
}, this);
// ^---- Nota
};
const obj = new Counter();
obj.add([2, 5, 9]);
obj.count;
// 3
obj.sum;
// 16
Poiché il parametro thisArg
(this
) viene fornito a forEach()
, viene passato a callback
ogni volta che viene richiamato, per essere utilizzato come valore this
.
Se si passa l'argomento della funzione utilizzando un'espressione della funzione a freccia il parametro thisArg
può essere omesso poiché le funzioni a freccia associano in modo lessicale il valore this
.
Una funzione di copia di oggetti
Il seguente codice crea una copia di un dato oggetto. Esistono diversi modi per creare una copia di un oggetto; il seguente è solo un modo e viene presentato per spiegare come funziona Array.prototype.forEach()
usando le funzioni di meta proprietà ECMAScript 5 Object.*
.
function copy(obj) {
const copy = Object.create(Object.getPrototypeOf(obj));
const propNames = Object.getOwnPropertyNames(obj);
propNames.forEach(function(name) {
const desc = Object.getOwnPropertyDescriptor(obj, name);
Object.defineProperty(copy, name, desc);
});
return copy;
}
const obj1 = { a: 1, b: 2 };
const obj2 = copy(obj1); // obj2 looks like obj1 now
Se l'array viene modificato durante l'iterazione, altri elementi potrebbero essere saltati.
L'esempio seguente registra "uno", "due", "quattro". Quando viene raggiunta la voce contenente il valore "due", la prima voce dell'intero array viene spostata, il che comporta il trasferimento di tutte le voci rimanenti in una posizione. Poiché l'elemento "quattro" è ora in una posizione precedente nell'array, "tre" verrà saltato. forEach()
non esegue una copia dell'array prima di iterare.
var words = ['uno', 'due', 'tre', 'quattro'];
words.forEach(function(word) {
console.log(word);
if (word === 'due') {
words.shift();
}
});
// uno
// due
// quattro
Appiattire un array
Il seguente esempio è qui solo per scopi didattici. Se si desidera appiattire un array usando metodi built-in, è possibile utilizzare Array.prototype.flat()
(che dovrebbe essere parte di ES2019 e già implementato in alcuni browser).
/**
* Flattens ha passato un array in un array dimensionale
*
* @params {array} arr
* @returns {array}
*/
function flatten(arr) {
const result = []
arr.forEach((i) => {
if (Array.isArray(i)) {
result.push(...flatten(i))
} else {
result.push(i)
}
})
return result
}
// Uso
const problem = [1, 2, 3, [4, 5, [6, 7], 8, 9]]
flatten(problem) // [1, 2, 3, 4, 5, 6, 7, 8, 9]
Polyfill
forEach()
è stato aggiunto allo standard ECMA-262 nella quinta edizione; in quanto tale potrebbe non essere presente in altre implementazioni dello standard. È possibile aggirare questo problema inserendo il seguente codice all'inizio degli script, consentendo l'uso di forEach()
nelle implementazioni che non lo supportano in modo nativo. Questo algoritmo è esattamente quello specificato in ECMA-262, 5a edizione, assumendo Object
e TypeError
hanno i loro valori originali e quel callback.call()
valuta il valore originale di 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. Let O be the result of calling toObject() passing the
// |this| value as the argument.
var O = Object(this);
// 2. Let lenValue be the result of calling the Get() internal
// method of O with the argument "length".
// 3. Let len be toUint32(lenValue).
var len = O.length >>> 0;
// 4. If isCallable(callback) is false, throw a TypeError exception.
// See: http://es5.github.com/#x9.11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 5. If thisArg was supplied, let T be thisArg; else let
// T be undefined.
if (arguments.length > 1) {
T = arguments[1];
}
// 6. Let k be 0.
k = 0;
// 7. Repeat while k < len.
while (k < len) {
var kValue;
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator.
// b. Let kPresent be the result of calling the HasProperty
// internal method of O with argument Pk.
// This step can be combined with c.
// c. If kPresent is true, then
if (k in O) {
// i. Let kValue be the result of calling the Get internal
// method of O with argument Pk.
kValue = O[k];
// ii. Call the Call internal method of callback with T as
// the this value and argument list containing kValue, k, and O.
callback.call(T, kValue, k, O);
}
// d. Increase k by 1.
k++;
}
// 8. return undefined.
};
}
Specifiche
Specifica | Stato | Commento |
---|---|---|
ECMAScript 5.1 (ECMA-262) The definition of 'Array.prototype.forEach' in that specification. |
Standard | Definizione iniziale Implementato in JavaScript 1.6. |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Array.prototype.forEach' in that specification. |
Standard | |
ECMAScript (ECMA-262) The definition of 'Array.prototype.forEach' in that specification. |
Living Standard |
Compatibilità con i browser
BCD tables only load in the browser