JavaScript: Quando devo usar forEach e map?
Sempre que vou avançando nas aulas dos cursos de JavaScript, reparei que no momento que eu saio dos loop convencionais e vou para um forEach, diversos alunos ficam meio perdidos no começo e a ideia deste post é eternizar em texto esta explicação, ajudando tanto quem for meu aluno ou aluna, quanto você que pode estar com essa dúvida agora.
Introdução
Se você pegar os 3 códigos abaixo, todos eles irão ter o mesmo retorno no navegador.
const nomes = ['Whinds', 'Freeway', 'Teste', 'Maria'];
for(let i = 0; i < nomes.length; i = i + 1 ) {
console.log('[for]', nomes[i]);
}
const nomes = ['Whinds', 'Freeway', 'Teste', 'Maria'];
nomes.forEach(function(nome, i) {
console.log('[forEach]', nome, i);
})
const nomes = ['Whinds', 'Freeway', 'Teste', 'Maria'];
nomes.map(function(nome, i) {
console.log('[forEach]', nome, i);
})
A princípio, da pra assumir que se o resultado é igual, eles fazem a mesma coisa. Mas fica claro se olharmos um pouco o forEach
e o map
que aqui não temos que nos preocupar com uma variável de indice (que normalmente chamamos de i), que serve para controlarmos o looping sendo ele um elemento que normalmente é incrementado ou decrementado. Porém é fácil notar que ao passo que não o escrevemos, esse dado é acessível para nós só que dessa vez recebemos ele como argumento da função que passamos para o forEach
e o map
. Para isso ficar mais claro, vamos dar uma olhada em uma possível implementação do forEach.
A implementação não funciona no modelo
array.map
earray.forEach
, pois para isso precisariamos mexer comprototype
e isso por si só já rende um post.
Entendendo o forEach
Anteriormente vimos que o forEach percorre todos os itens de um array, tal como o loop for normal, isso é porque internamente ele possui um lop for. Se fossemos implementá-lo ele sairia algo como o código abaixo:
function nossoForEach(arr, funcao) {
for(let i = 0; i < arr.length; i = i + 1) {
funcao(arr[i], i);
}
}
nossoForEach(['nome', 'nome2'], function(nome, indice) {
console.log(nome, indice)
})
Sempre que você for fazer um loop for, vale mais a pena usar um forEach, pois ele elimina a carga mental de ter que lidar com as variáveis de controle e por consequência pode ajudar a deixar o código mais fácil de ler, levando em conta que essa é uma forma super usada no mundo JavaScript em geral.
Entendendo o map
Na prática como vimos no começo do post, o map e o forEach parecem fazer a mesma coisa, porém a difrença vem quando analisamos o retorno do que sai delas a diferença fica clara.
const nomes = ['Whinds', 'Freeway', 'Teste', 'Maria'];
const retornoForEach = nomes.forEach((nomeAtual) => {
console.log(nomeAtual);
return nomeAtual.toUpperCase();
})
console.log(retornoForEach) // undefined
const nomes = ['Whinds', 'Freeway', 'Teste', 'Maria'];
const retornoMap = nomes.map((nomeAtual) => {
console.log(nomeAtual);
return nomeAtual.toUpperCase();
})
console.log(retornoMap) // ['WHINDS', 'FREEWAY', 'TESTE', 'MARIA']
Enquanto o forEach foi feito para ser uma alternativa ao loop for, o map foi feito para fazemos operação de transformação/alteração nos itens de um array e ao final dessas operações ter uma lista nova com a mesma quantidade de itens da lista base.
Se fossemos implementar o map, cairiamos em um código nessa linha:
function nossoMap(arr, funcao) {
const novoArray = [];
for(let i = 0; i < arr.length; i = i + 1) {
novoArray.push(funcao(arr[i], i));
}
return novoArray
}
nossoMap(['nome', 'nome2'], function(nome, indice) {
console.log(nome, indice)
})
Isso facilita para fazermos concatenações de operações como fazer um map e imendar com um filter, dado que o retorno do map é um array, podemos escrever um código nessa linha: .map().filter()
.
Conclusão
Por esse post é só, espero que tenha ficado claro que caso queiramos somente uma forma mais elegante para trabalhar com o for usamos o .forEach
e caso queiramos transformar/alterar valores ou mesmo concatenar operações em cima de arrays o .map
é o mais indicado.
Vejo você no próximo artigo. Epero que tenha gostado, em breve trarei mais dicas, não deixe de me seguir nas minhas redes sociais, dar mma passada no meu canal do youtube @devsoutinho e acompanhar meus outros artigos em meu site pessoal https://mariosouto.com.
Referências
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach