Articolo originale: The Differences Between forEach() and map() that Every Developer Should Know

JavaScript ha utili metodi che aiutano a iterare sui nostri array. I due più comunemente usati per iterare sono Array.prototype.map() e Array.prototype.forEach().

Ma credo che rimangano un po' poco chiari, soprattutto per i principianti. Perché se entrambi iterano e hanno un output, quale è la differenza?

In questo articolo vedremo le seguenti cose:

  • Definizioni
  • Il valore restituito
  • Abilità di concatenare altri metodi
  • Mutabilità
  • Velocità della Performance
  • Pensieri conclusivi

Definizioni

Il metodomap riceve una funzione come parametro. Poi lo applica ad ogni elemento e restituisce un array interamente nuovo popolato con i risultati delle chiamate della funzione data.

Questo significa che rstituisce un nuovo array che contiene un'immagine di ogni elemento dell'array. Ritornerà sempre lo stesso numero di elementi.


const mioSplendidoArray = [5, 4, 3, 2, 1]

mioSplendidoArray.map(x => x * x)

// >>>>>>>>>>>>>>>>> Output: [25, 16, 9, 4, 1]

Come map, il metodo forEach riceve una funzione come argomento e la esegue una volta per ogni elemento dell'array. Però, invece di restituire un nuovo array come map, restituisce undefined.

const mioSplendidoArray = [
  { id: 1, nome: "john" },
  { id: 2, nome: "Ali" },
  { id: 3, nome: "Mass" },
]

mioSplendidoArray.forEach(elemento => console.log(elemento.nome))
// >>>>>>>>> Output : john
//                    Ali
//                    Mass

1. Il valore restituito

La prima differenza tra map() e forEach() è il valore restituito. Il metodo forEach() restituisce undefined e map() restituisce un nuovo array con gli elementi trasformati. Anche se fanno la stessa cosa, il valore restituito rimane differente.

const mioSplendidoArray = [1, 2, 3, 4, 5]
mioSpendidoArray.forEach(x => x * x)
//>>>>>>>>>>>>>valore restituito: undefined

mioSplendidoArray.map(x => x * x)
//>>>>>>>>>>>>>valore restituito: [1, 4, 9, 16, 25]

2. Abilità di concatenare altri metodi

La seconda differenza tra questi metodi per array è il fatto che map è concatenabile. Questo significa che puoi attaccare reduce(), sort(), filter() e altri metodi per array dopo avere usato map() su un array.

Questo non lo puoi fare con forEach(), perché, come puoi avere indovinato, restituisce undefined.`ù

const mioSplendidoArray = [1, 2, 3, 4, 5]
mioSplendidoArray.forEach(x => x * x).reduce((totale, valore) => totale + valore)
//>>>>>>>>>>>>> Uncaught TypeError: Cannot read property 'reduce' of undefined
mioSplendidoArray.map(x => x * x).reduce((totale, valore) => totale + valore)
//>>>>>>>>>>>>>restituisce valore: 55

3. Mutabilità

In generale, la parola "mutare"Q significa cambiare, alternare, alterare, modificare. E in JavaScript ha lo stesso significato.

Un oggetto mutabile è un oggetto il cui stato può essere mutato dopo che è stato creato. Quindi, potremmo chiederci come si comportano forEach e map a riguardo della mutabilità.

Consultando la  documentazione del MDN scopriamo che:

forEach() non muta l'array su cui è invocato. (Però la funzione callback potrebbe farlo).

map() non muta l'array su cui è invocato. (Però la funzione callback potrebbe farlo).

JavaScript è strano.

Gif

Qui vediamo definizioni simili, e sappiamo che entrambi ricevono una funzione callback come argomento. Quale dei due metodi si avvantaggia dell'immutabilità?

Secondo me questa definizione non è abbastanza chiara. E per sapere quale dei due non muta l'array originale dobbiamo prima vedere come questi due metodi funzionao.

Il metodo map()restituisce un array completamente nuovo con gli elementi trasformati e lo stesso numero di elementi. Nel caso di forEach(), anche se restituisce undefined, cambierà l'array originale con callback.

Quindi, possiamo vedere chiaramente che map() usa l'immutabilità, mentre forEach() è un metodo che muta.

4. Velocità della performance

Riguardo la velocità di performance, sono un pochino differenti. È importante? Beh, dipende da alcune cose come il tuo computer, con quanti dati hai a che fare, e così via.

Puoi provare per conto tuo con questo esempio o con jsPerf per vedere quale è più veloce.

const mioSplendidoArray = [1, 2, 3, 4, 5]

const inizioForEach = performance.now()
mioSplendidoArray.forEach(x => (x + x) * 10000000000)
const fineForEach = performance.now()
console.log(`Velocità [forEach]: ${fineForEach - inizioForEach} milisecondi`)

const inizioMap = performance.now()
mioSplendidoArray.map(x => (x + x) * 10000000000)
const fineMap = performance.now()
console.log(`Velocità [map]: ${fineMap - inizioMap} milisecondi`)

Pensieri conclusivi

Come sempre, la scelta tra map() e forEach() dipende da quello che devi fare. Se vuoi cambiare, alterare, o usare i dati, dovresti scegliere map() perché restituisce un nuovo array con i dati trasformati.

Ma, se non hai bisogno del nuovo array, non usare map(), usa invece forEach() o perfino un ciclo for.

Spero che questo post sia utile a chiarire la differenza tra i due metodi. Se ci sono altre differenze condividile twittando questo articolo, altrimenti grazie per averlo letto.