forEach JavaScript: Como Potencializar seus Loops em Arrays

JavaScript

forEach JavaScript: Como Potencializar seus Loops em Arrays

Gabriel Nascimento
Escrito por Gabriel Nascimento em 11 de agosto de 2020

O método forEach é um incrível recurso JavaScript com o objetivo de substituir o clássico loop for por um código:

  • Mais limpo;
  • Mais legível;
  • E de fácil manutenção.

Sendo um recurso popular entre os desenvolvedores JavaScript, ele contribui muito para sua vida profissional.

Afinal grande parte dos projetos hoje já adota esse método.

Porém é normal ficar meio perdido no começo, quando sai dos loops convencionais e experimenta o forEach.

Por isso continue lendo esse artigo para você descobrir como lidar com laços de repetição de uma forma muito mais fácil.

O que é e como funciona o método forEach JavaScript?

O forEach é um método muito útil quando precisamos acessar todos os elementos de um Array (um por um) para depois fazer algo com eles.

Por exemplo, considere o caso no qual desejamos mostrar no console todos os itens de uma lista de nomes. Ao utilizar o clássico loop for, temos algo assim:

let nomes = ['maria', 'josé', 'joão'];

for(var i = 0; i < nomes.length; i++) {
  console.log(nomes[i]);
}

// Resultado: maria, josé, joão

Funciona? Sim, mas podemos melhorar o código e ter o mesmo efeito…

Para isso, invocamos a função forEach() do próprio Array, e passamos uma função de retorno:

let nomes = ['maria', 'josé', 'joão'];

nomes.forEach(function(nome) {
  console.log(nome);
});

// Resultado: maria, josé, joão

Note que, dentro do forEach(), passamos uma função anônima function(nome){...}, também chamada de função callback

Essa função será executada para cada elemento dentro da lista. E a cada iteração, o valor do elemento é atribuído à variável passada como parâmetro no callback, no caso a variável nome

esquemático do método forEach JavaScript

Claro, apenas imprimimos os valores no console, mas podemos fazer qualquer coisa com o valor da variável dentro da função callback. Inclusive passar como parâmetro de outros métodos.

Porém a função callback não precisa ser anônima. Você pode criar a função e depois passá-la como parâmetro ao forEach():

let nomes = ['maria', 'josé', 'joão'];

function imprimeNome(nome) {
  console.log(nome);
}

nomes.forEach(imprimeNome);

// Resultado: maria, josé, joão

Nos 2 casos, o resultado é exatamente o mesmo…

Acessar cada elemento do Array não poderia ser mais fácil!

O método forEach() existe em todos os Arrays, afinal todos eles herdam os vários métodos do Array.prototype.

Quando usar o forEach JavaScript?

dúvidas de quando usar o forEach JavaScript

Apesar de parecido, o forEach se comporta de maneira diferente e possui menos flexibilidade que o loop for.

Na maioria dos casos, depende apenas da sua preferência como desenvolvedor. No entanto, é importante considerar 3 pontos antes de escolher entre os dois:

1 – O forEach não manipula o Array original

Você precisa estar atento ao fato de que o Array processado pelo forEach JavaScript é determinado antes da função callback ser invocada…

Ou seja, se os itens do Array forem alterados enquanto o método forEach() estiver executando, as alterações serão ignoradas

Analise o código a seguir para entender o que isso significa:

let nomes = ['maria', 'josé', 'joão'];

nomes.forEach(function(nome) {
  nomes[2] = 'pedro'; // essa alteração será ignorada
  console.log(nome);
}); 

// Resultado: maria, josé, joão

E o mesmo vale se elementos forem adicionados ou removidos depois da chamada do método, dá seguinte maneira:

let nomes = ['maria', 'josé', 'joão'];

nomes.forEach(function(nome) {
  nomes.push('pedro'); // essa adição será ignorada
  console.log(nome);
});

// Resultado: maria, josé, joão

Perceba que o valor passado para o callback sempre será o valor no momento em que o forEach() for executado pela primeira vez.

Porém isso não quer dizer que os valores não são adicionados ao Array…

Se você executar um segundo console.log() na lista de nomes, notará que 'pedro' foi adicionado várias vezes no Array. Uma para cada repetição do loop:

let nomes = ['maria', 'josé', 'joão'];

nomes.forEach(function(nome) {
  nomes.push('pedro'); // essa adição será ignorada
  console.log(nome);
});

console.log(nomes);

// Resultado: [ 'maria', 'josé', 'joão', 'pedro', 'pedro', 'pedro' ]

Caso você precise alterar os valores do Array durante a execução, recomendo que use o método map().

2 – O escopo da variável é diferente no forEach

Uma coisa boa do método forEach() é o fato da função callback manter suas variáveis dentro do seu escopo.

Assim caso você reutilize um variável externa dentro do forEach(), elas não vão interferir uma na outra e a variável externa manterá seu valor (o que evita a ocorrência de conflitos).

const num = 4;
const arr = [0, 1, 2];

arr.forEach(function(num) {  
  console.log(num);
});

//Resultado: 0, 1, 2

console.log(num);

//Resultado: 4

Claro, uma boa prática é não escrever 2 variáveis com o mesmo nome, como no exemplo acima.

Mas a casos em que você precisa modificar uma variável externa dentro do laço de repetição…

Para isso, explore outras alternativas de loop como for...in, for...of e o clássico for.

3 – Você pode sair do loop for mais cedo com break

Quando usamos a palavra-chave break, podemos impedir que o loop continue assim que ele encontrar uma condição específica.

Mas o método forEach() não suporta a instrução break

Então se você quiser interromper o laço de repetição mais cedo, vai precisar de outra alternativa JavaScript, como for...of ou o clássico loop for:

for (let i = 0; i < nomes.length; i++) {
  if (nomes[i] === 'maria') {
    console.log('EU AMO A MARIA');
    break;
  }
}

A maneiras de simular esse comportamento no forEach, mas não são recomendadas.

Parâmetros opcionais do método forEach JavaScript

Vimos a função forEach() apenas em sua forma mais básica… aliás sua sintaxe completa possui vários argumentos opcionais que podem ser muito úteis para você:

array.forEach((value, index, arr) => {...}, thisArg);

Já conhecemos a função de callback, mas ela na realidade pode receber até 3 parâmetros:

  • value (obrigatório): O valor do item atual;
  • index (opcional): O número de índice do item atual;
  • arr (opcional): O próprio Array sendo percorrido.

E o segundo argumento thisArg permite que o contexto this seja alterado, mas é raramento usado.

Por fim, vejamos um exemplo de uso do forEach JavaScript com seus parâmetros opcionais:

let nomes = ['maria', 'josé', 'joão'];

nomes.forEach( function(value, index, arr) {
  console.log(`Nome ${index + 1} de ${arr.length}: ${value}`);
});

// Nome 1 de 3: maria
// Nome 2 de 3: josé
// Nome 3 de 3: joão

Conclusão

No final do dia, os resultados do loop for e forEach são semelhantes, apesar de algumas pequenas situações caso a caso…

Mas basta uma olhada no forEach, para ver que nele temos uma escrita mais simples… 

Além de não precisarmos nos preocupar com a variável índice (normalmente chamada de i) para controlar o looping.

Então sempre que você usar um loop for, pense em mudar para um forEach. Pois ele elimina a carga mental de lidar com variáveis de controle, além de deixa seu código mais fácil de ler.

Espero que você tenha gostado do artigo! Se tiver alguma dúvida ou opinião, seu comentário é sempre muito bem vindo:

Hey,

o que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

5 Replies to “forEach JavaScript: Como Potencializar seus Loops em Arrays”

Edwin

const num = 4;
const arr = [0, 1, 2];

arr.forEach(function(num) {
console.log(num);
});

//Resultado: 1, 2, 3

console.log(num);

//Resultado: 4

No caso a primeira saída dentro do forEach seria ‘0, 1,2’ né?

Gabriel Nascimento

Sim, é isso mesmo! Ele mostra os valores do array.

Edwin

Boa tarde, no caso do seu exemplo me confundiu um pouco, mas vi que o comentário de saída está errado:

const num = 4;
const arr = [0, 1, 2];

arr.forEach(function(num) {
console.log(num);
});

//Resultado: 1, 2, 3

console.log(num);

//Resultado: 4

Gabriel Nascimento

Boa tarde, sim, está mesmo errado…
Obrigado por me avisar. Se não fosse você, acho que nunca teria visto esse erro. 😉
Já realizei a correção também.

Gabriel Nascimento