Qual a diferença entre o método MAP e o FOREACH

Ao se aprofundar no mundo do JavaScript é comum termos duvidas em alguns métodos que aparentemente fazem a mesma coisa que é percorrer um Array executando um callback em cada elemento, e então fica o questionamento de quando usar cada um.
Inicialmente as definições dos dois métodos pode ser bem confusas, mas isso até entender a premissa deles.

Map e ForEach

Os dois métodos o Map e o ForEach recebem um função como parâmetro (callback). Logo após o método inicia a função em cada um elemento do Array que está sendo percorrido, porem a diferença entre cada um está agora. O Método Map ele retorna um novo Array que contem os resultados da função que foi executada, já o ForEach retorna o valor undefined. Que loucura né!?. Então apesar de fazerem exatamente a mesma coisa eles tem retornos diferentes. Abaixo deixo um exemplo.

const valor = [1, 2, 3, 4, 5]
let foreach = valor.forEach(x => x * x)
console.log(foreach); // undefined

let map = valor.map(x => x * x)
console.log(map); //[1, 4, 9, 16, 25]

Pontos importantes

Outra diferença que é muito importante é o fato do método map retornar um Array novo como resultado do callback. Ele não modifica o Array original, ele gera um novo e deixa o outro intacto. Já o ForEach apesar do seu retorno ser um valor undefined ele pode modificar o Array original dentro do callback. Esses conceitos levantam questões sobre a mutabilidade dos métodos, e pelo que vimos ao utilizar o Map devemos estar cientes que ele baseia-se na imutabilidade diferente do ForEach que é mutável permitindo alterar o Array original através da função de callback.

Encadeamento

E por fim temos o encadeamento de métodos que na minha opinião é algo muito importante por ser versátil quando queremos algo mais especifico do retorno do callback.
O método map ele tem esse suporte, então se você precisa organizar por ordem alfabética ou numérica aquele Array que está todo misturado. É possível utilizar o método map juntamente com o sort. Não apenas o sort mas outros métodos também como o filter e reduce podem ser usados para seus respectivos objetivos.

Já com ForEach isso não é possível pois como vimos anteriormente, o valor de retorno no ForEach é undefined, e como iterar sobre um valor que é undefined?. Não é possível.

Conclusão

Vimos que os métodos fazem as mesmas coisas porém tem suas peculiaridades, portanto se você não precisar que o retorno da função callback seja um Array, utilize o ForEach.
Caso o objetivo seja modificar os dados do Array opte pelo map já que ele não modificará o original. Abaixo deixo um exemplo de uso do ForEach e do Map

<ul>
<li class="meus-itens">Valor 1</li>
<li class="meus-itens">Valor 2</li>
<li class="meus-itens">Valor 3</li>
</ul>
const items = document.querySelectorAll(".meus-itens");

items.forEach((e) => {
e.style.backgroundColor = 'yellow';
})

Nesse exemplo acima o uso do ForEach é perfeito pois não precisa de um novo Array e o valor de items é um HTMLColection. Ao tentarmos trocar o método pelo Map vamos obter o seguinte erro:

erro ao usar o metodo map

Isso é tudo, até a próxima.

Veja também: Listagem de itens da API JSONPlaceholder

Referências: Array.prototype.map() – JavaScript | MDN (mozilla.org), Array.prototype.forEach() – JavaScript | MDN (mozilla.org)