JavaScript: diferença entre .forEach () e .map ()


115

Eu sei que houve muitos tópicos como este. E eu sei o básico:.forEach() opera na matriz original e .map()na nova.

No meu caso:

function practice (i){
    return i+1;
};

var a = [ -1, 0, 1, 2, 3, 4, 5 ];
var b = [ 0 ];
var c = [ 0 ];
console.log(a);
b = a.forEach(practice);
console.log("=====");
console.log(a);
console.log(b);
c = a.map(practice);
console.log("=====");
console.log(a);
console.log(c);

E esta é a saída:

[ -1, 0, 1, 2, 3, 4, 5 ]
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
undefined
=====
[ -1, 0, 1, 2, 3, 4, 5 ]
[ 0, 1, 2, 3, 4, 5, 6 ]

Não consigo entender por que usar practicealtera o valor de bpara undefined.
Desculpe se esta é uma pergunta boba, mas sou muito novo nessa linguagem e as respostas que encontrei até agora não me satisfizeram.


49
É simples assim: .map retorna um novo array , .forEach mas não retorna nada . Basicamente, se você deseja obter uma forma modificada do array anterior, você usa .map, se não quiser, você usa .forEach.
user4642212


@Xufox - Eu li este tópico antes de criar um novo, mas a resposta não me satisfez.
DzikiChrzan

Não diga apenas que não o satisfez. Como exatamente isso não responde à sua pergunta (você leu todas as respostas?)? Qual é a sua pergunta específica que não foi abordada pelo alvo duplicado proposto?
user4642212

@Xufox Essa questão lida com funções auto-implementadas e não é realmente sobre as funções ES5 padronizadas.
toque em

Respostas:


145

Eles não são um e o mesmo. Deixe-me explicar a diferença.

forEach: Itera sobre uma lista e aplica alguma operação com efeitos colaterais a cada membro da lista (exemplo: salvar cada item da lista no banco de dados)

map: Isso itera sobre uma lista, transforma cada membro dessa lista e retorna outra lista do mesmo tamanho com os membros transformados (exemplo: transformar a lista de strings em maiúsculas)

Referências

Array.prototype.forEach () - JavaScript | MDN

Array.prototype.map () - JavaScript | MDN


4
E como a Xufox disse - .forEach não retorna nada, esse é o caso. Obrigado pela ajuda! Vou marcar esta resposta em 10 minutos.
DzikiChrzan

lista de retorno de mapa e forEach not. OK
Ashad Nasim

62
  • Array.forEach “Executa uma função fornecida uma vez por elemento da matriz.”

  • Array.map “Cria uma nova matriz com os resultados da chamada de uma função fornecida em cada elemento desta matriz.”

Portanto, forEachnão retorna nada. Ele apenas chama a função para cada elemento do array e então está feito. Portanto, tudo o que você retornar dentro dessa função chamada é simplesmente descartado.

Por outro lado, map irá de forma semelhante chamar a função para cada elemento do array, mas em vez de descartar seu valor de retorno, ele irá capturá-lo e construir um novo array desses valores de retorno.

Isso também significa que você pode usar maponde quer que esteja, forEachmas ainda assim não deve fazer isso, para não coletar os valores de retorno sem qualquer propósito. É apenas mais eficiente não coletá-los se você não precisar deles.


De nota: em 2015, seria discutível que forEachteria sido "mais eficiente" do que mapespecialmente se um polyfill fosse necessário para oferecer suporte forEachem um navegador mais antigo (IE8 ou 9). Você não precisa atribuir o retorno de mapa nada; o valor de retorno deve ter o lixo coletado imediatamente após os mapretornos, quando o retorno de mapnão é atribuído.
Cowbert

3
@cowbert Só porque algo é coletado como lixo imediatamente, isso não significa que você não está sendo atingido pelas alocações necessárias. Assim forEach, conceitualmente, ainda será mais eficiente e mais adequado para tarefas em que você não precisa coletar resultados. E eu não sei sobre você, mas em 2015, eu não estava mais desenvolvendo para o IE8 (que aliás. Também não suportava map); e suporte para IE9 + forEach. E, na verdade, um mês após minha resposta, a Microsoft encerrou o suporte para esses navegadores.
cutucar

Tanto forEach quanto map têm garantia de processar os elementos na mesma ordem?
Quentin 2 de

1
@ Quentin2 É, também, as duas funções são síncronas, por isso mape forEachas chamadas só irá retornar uma vez que todo o conjunto foi loop através eo retorno tem sido chamado para cada um.
toque em

25
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| | foreach | mapa |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Funcionalidade | Executa determinada operação em cada | Executa determinada "transformação" em |
| | elemento da matriz | "cópia" de cada elemento |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Valor de retorno | Retorna indefinido | Retorna uma nova matriz com transformado |
| | | elementos deixando de volta a matriz original |
| | | inalterado |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +
| Preferível | Executando não transformação como | Obtendo array contendo saída de |
| cenário de uso | processamento em cada elemento. | algum processamento feito em cada elemento |
| e exemplo | | da matriz. |
| | Por exemplo, salvar todos os elementos em | |
| | o banco de dados | Por exemplo, obtendo array de |
| | | comprimentos de cada string no |
| | | array |
+ ---------------- + -------------------------------- ----- + --------------------------------------- +

Por favor edite seu post e mostrar o texto real em vez de imagens. Outros não podem copiar e colar de sua imagem, pesquisar em sua imagem ou ajudar a melhorar o conteúdo do texto na imagem. Veja aqui os detalhes. Obrigado.
Pang

2
Isso pode ajudá-lo a desenhar tabelas de arte ASCII: webapps.stackexchange.com/q/6700/126269
Pang


7

forEach: Se você deseja executar uma ação nos elementos de um Array e é o mesmo que você usa para loop. O resultado desse método não nos dá uma saída, apenas um loop pelos elementos.

map: Se você deseja executar uma ação nos elementos de um array e também deseja armazenar a saída de sua ação em um Array. Isso é semelhante ao loop for dentro de uma função que retorna o resultado após cada iteração.

Espero que isto ajude.


5

A diferença está no que eles retornam. Após a execução:

arr.map()

retorna uma matriz de elementos resultantes da função processada; enquanto:

arr.forEach()

retorna indefinido.


5

Análise de desempenho Os loops For têm um desempenho mais rápido do que map ou foreach conforme o número de elementos em uma matriz aumenta.

let array = [];
for (var i = 0; i < 20000000; i++) {
  array.push(i)
}

console.time('map');
array.map(num => {
  return num * 4;
});
console.timeEnd('map');


console.time('forEach');
array.forEach((num, index) => {
  return array[index] = num * 4;
});
console.timeEnd('forEach');

console.time('for');
for (i = 0; i < array.length; i++) {
  array[i] = array[i] * 2;

}
console.timeEnd('for');

Aqui está o resultado no meu computador:map: 1642ms forEach: 885ms for: 748ms
Flavio Vilante


1

Algo a ser destacado é que foreach ignora os valores não inicializados, enquanto map não.

var arr = [1, , 3];

arr.forEach(function(element) {
    console.log(element);
});
//Expected output: 1 3

console.log(arr.map(element => element));
//Expected output: [1, undefined, 3];

0

Diferença entre forEach () e map ()

forEach () apenas percorre os elementos. Ele joga fora os valores de retorno e sempre retorna indefinido. O resultado desse método não nos dá uma saída.

map () percorre os elementos aloca memória e armazena os valores de retorno iterando o array principal

Exemplo:

   var numbers = [2,3,5,7];

   var forEachNum = numbers.forEach(function(number){
      return number
   })
   console.log(forEachNum)
   //output undefined

   var mapNum = numbers.map(function(number){
      return number
   })
   console.log(mapNum)
   //output [2,3,5,7]

map () é mais rápido que forEach ()



0

forEach () :

valor de retorno: indefinido

originalArray: modificado após a chamada do método

mapa () :

valor de retorno: novo Array preenchido com os resultados da chamada de uma função fornecida em cada elemento do array de chamada

originalArray: não modificado após a chamada do método

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.