A única diferença que vejo em map e foreach é que map
está retornando uma matriz e forEach
não está. Porém, eu nem entendo a última linha do forEach
método " func.call(scope, this[i], i, this);
". Por exemplo, não é " this
" e " scope
" referindo-se ao mesmo objeto e não é this[i]
e i
referindo-se ao valor atual no loop?
Notei em outro post que alguém disse "Use forEach
quando quiser fazer algo com base em cada elemento da lista. Você pode adicionar coisas à página, por exemplo. Essencialmente, é ótimo para quando você deseja" efeitos colaterais ". Não sei o que significa efeitos colaterais.
Array.prototype.map = function(fnc) {
var a = new Array(this.length);
for (var i = 0; i < this.length; i++) {
a[i] = fnc(this[i]);
}
return a;
}
Array.prototype.forEach = function(func, scope) {
scope = scope || this;
for (var i = 0, l = this.length; i < l; i++) {
func.call(scope, this[i], i, this);
}
}
Finalmente, existem outros usos reais para esses métodos em javascript (uma vez que não estamos atualizando um banco de dados) além de manipular números como este:
alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.
Obrigado por qualquer resposta.
fonte
map
eforEach
? Tudo o que recebo do Google são especificações de uso e tutoriais.Respostas:
A diferença essencial entre
map
eforEach
em seu exemplo é queforEach
opera nos elementos da matriz original, enquantomap
retorna explicitamente uma nova matriz como resultado.Com
forEach
você está realizando alguma ação com - e opcionalmente alterando - cada elemento na matriz original. OforEach
método executa a função fornecida para cada elemento, mas não retorna nada (undefined
). Por outro lado,map
percorre o array, aplica uma função a cada elemento e emite o resultado como um novo array .O "efeito colateral"
forEach
é que a matriz original está sendo alterada. "Nenhum efeito colateral"map
significa que, no uso idiomático, os elementos originais do array não são alterados; a nova matriz é um mapeamento um para um de cada elemento na matriz original - a transformação de mapeamento sendo sua função fornecida.O fato de não haver banco de dados envolvido não significa que você não terá que operar em estruturas de dados, o que, afinal, é uma das essências da programação em qualquer linguagem. Quanto à sua última pergunta, seu array pode conter não apenas números, mas objetos, strings, funções, etc.
fonte
.map
pode fazer tudo o que.forEach
pode fazer (incluindo modificar elementos), ele apenas retorna uma nova lista construída a partir da função iteradora..map()
cria uma nova matriz e não altera a original. Você realmente poderia modificar o array que está sendo mapeado, mas isso seria no mínimo não idiomático, se não sem sentido..forEach()
, embora semelhante, aplica sua função a cada elemento, mas sempre retornaundefined
. Apesar de tudo o que foi dito acima, o OP também está perguntando sobre suas próprias funções específicas adicionadas ao protótipo do array; não havia ES5 aqui no passado.forEach
faça que você não possa fazermap
. Você poderia simplesmente não se preocupar com o valor de retorno demap
e teria umforEach
. A diferença é que ele é muito ineficaz de usarmap
para tarefas em que você não deseja criar uma nova matriz com base nos resultados. Então, para aqueles, você usaforEach
.for
loop simples e antigo . Não discordo que haja alguma diferença na "eficácia", mas também não acho que alguém esteja argumentando que um tem alguma magia que o outro não pode realizar de alguma forma. Embora haja, de fato, uma coisa quemap
não se pode fazer: não retornar um array. Não há valor em ter JS correspondeu às expectativas de outras línguas como ao comportamento dos favoritos funcionais comomap
,reduce
,filter
, etc. Por exemplo, você poderia implementarreduceRight
usando blocos de construção semelhantes, mas por que não usarreduceRight
?b.val = b.val**2
dentro do objeto retornado . É exatamente isso que estamos dizendo que é realmente possível, mas confuso e não idiomático. Normalmente, você simplesmente retorna o novo valor, e não também o atribui à matriz original:a=[{val:1},{val:2},{val:3},{val:4}]; a.map((b)=>{b.val**2}); JSON.stringify(a);
A principal diferença entre os dois métodos é conceitual e estilística: você usa
forEach
quando quer fazer algo para ou com cada elemento de uma matriz (fazer "com" é o que a postagem que você cita quer dizer com "efeitos colaterais", eu acho) , enquanto você usamap
quando deseja copiar e transformar cada elemento de uma matriz (sem alterar o original).Como
map
eforEach
chamam uma função em cada item de uma matriz, e essa função é definida pelo usuário, não há quase nada que você possa fazer com um e não com o outro. É possível, embora feio, usá-lomap
para modificar uma matriz no local e / ou fazer algo com os elementos da matriz:mas muito mais limpo e mais óbvio quanto à sua intenção de uso
forEach
:Especialmente se, como geralmente é o caso no mundo real,
el
for uma variável legível útil:Da mesma forma, você pode usar facilmente
forEach
para fazer uma nova matriz:mas é mais limpo de usar
map
:Observe também que, porque
map
formar uma nova matriz, ela provavelmente incorre em pelo menos algum impacto de desempenho / memória quando tudo o que você precisa é iteração, especialmente para matrizes grandes - consulte http://jsperf.com/map-foreachQuanto ao motivo de você querer usar essas funções, elas são úteis sempre que você precisa fazer manipulação de array em javascript, o que (mesmo que estejamos falando apenas de javascript em um ambiente de navegador) é muito comum, quase a qualquer momento você está acessando um array que não está escrevendo manualmente em seu código. Você pode estar lidando com uma matriz de elementos DOM na página, ou dados extraídos de uma solicitação AJAX ou dados inseridos em um formulário pelo usuário. Um exemplo comum que encontro é a extração de dados de uma API externa, onde você pode querer usar
map
para transformar os dados no formato que deseja e, em seguida, usarforEach
para iterar em seu novo array a fim de exibi-los para o usuário.fonte
.map()
o tempo todo para modificar elementos embutidos. Fiquei com a impressão de que era o principal benefício de usar.map
over.forEach
.map
pode modificar elementos, sim, mas criaria um array de que você não precisa. Você também deve considerar como escolher um ou outro permite que o leitor adivinhe se você tem ou não efeitos colateraisA resposta votada (de Ken Redler) é enganosa.
Um efeito colateral na ciência da computação significa que uma propriedade de uma função / método altera um estado global [wiki] . Em certo sentido, isso também pode incluir a leitura de um estado global, ao invés de argumentos. Na programação imperativa ou OO, os efeitos colaterais aparecem na maioria das vezes. E provavelmente você está fazendo uso dele sem perceber.
A diferença significativa entre
forEach
emap
é quemap
aloca memória e armazena o valor de retorno, enquanto oforEach
joga fora. Veja as especificações do emca para obter mais informações.Já o motivo pelo qual as pessoas dizem que
forEach
é usado quando você quer um efeito colateral é que o valor de retorno deforEach
é sempreundefined
. Se não tiver efeito colateral (não muda o estado global), a função está apenas desperdiçando tempo de CPU. Um compilador otimizado irá eliminar este bloco de código e substituí-lo pelo valor final (undefined
).A propósito, deve-se observar que o JavaScript não tem restrições aos efeitos colaterais. Você ainda pode modificar a matriz original dentro
map
.fonte
Esta é uma bela pergunta com uma resposta inesperada.
O seguinte é baseado na descrição oficial de
Array.prototype.map()
.Não há nada que
forEach()
possa fazer quemap()
não possa. Ou seja,map()
é um superconjunto estrito deforEach()
.Embora
map()
seja normalmente usado para criar um novo array, também pode ser usado para alterar o array atual. O exemplo a seguir ilustra isso:No exemplo acima,
a
foi convenientemente definido de modo quea[i] === i
parai < a.length
. Mesmo assim, ele demonstra o podermap()
e, em particular, sua capacidade de alterar o array no qual é chamado.Nota1:
A descrição oficial implica que
map()
pode até alterar o comprimento do array no qual é chamado! No entanto, não vejo (uma boa) razão para fazer isso.Nota2:
Embora o
map()
mapa seja um superconjunto deforEach()
,forEach()
ainda deve ser usado onde se deseja a alteração de um determinado array. Isso deixa suas intenções claras.Espero que tenha ajudado.
fonte
mapped = a.map(function (x, i, arr) { arr[i] = x * x * x; return x * x; });.
a.forEach(function(x, i, arr) { ...
, o que, novamente, é uma maneira conceitualmente mais correta quando há uma intenção de transformar cada item original em oposição a mapear valores de uma matriz para outraVocê pode usar
map
como se fosseforEach
.Mas fará mais do que o necessário.
scope
pode ser um objeto arbitrário; não é necessariamentethis
.Quanto a saber se existem usos reais para
map
eforEach
, também perguntar se existem usos reais parafor
ouwhile
loops.fonte
scope = scope || this
significa "sescope
for falso (indefinido, nulo, falso, etc), defina o escopothis
e continue".Embora todas as perguntas anteriores estejam corretas, eu definitivamente faria uma distinção diferente. O uso de
map
eforEach
pode implicar intenção.Eu gosto de usar
map
quando estou simplesmente transformando os dados existentes de alguma forma (mas quero ter certeza de que os dados originais não foram alterados.Gosto de usar
forEach
quando estou modificando a coleção no local.Por exemplo,
Minha regra é certificar-se de que
map
você está sempre criando algum novo objeto / valor para retornar para cada elemento da lista de fontes e retornando -o ao invés de apenas realizar alguma operação em cada elemento.A menos que você tenha alguma necessidade real de modificar a lista existente, realmente não faz sentido modificá-la no local e se encaixa melhor em estilos de programação funcionais / imutáveis.
fonte
Resposta TL; DR -
map sempre retorna outro array.
forEach não. Cabe a você decidir o que ele faz. Retorne um array se quiser ou faça outra coisa se não quiser.
A flexibilidade é desejável em certas situações. Se não for para o que você está lidando, use o mapa.
fonte
Mais uma vez, sinto-me como um necromante adicionando uma resposta a uma pergunta que foi feita há 5 anos (felizmente, há atividades bem recentes, então não sou o único a perturbar os mortos :).
Outros já postaram sobre sua principal dúvida em relação à diferença entre as funções. Mas pelo...
... é engraçado você perguntar. Hoje mesmo escrevi um pedaço de código que atribui uma série de valores de uma expressão regular a várias variáveis usando mapa para transformação. Foi usado para converter uma estrutura baseada em texto muito complicada em dados visualizáveis ... mas para simplificar, vou oferecer um exemplo usando strings de data, porque provavelmente são mais familiares para todos (embora, se meu problema fosse realmente com datas , em vez de mapa, eu teria usado objeto-data, que teria feito o trabalho esplendidamente por conta própria).
Então ... embora isso fosse apenas um exemplo - e fizesse apenas uma transformação muito básica para os dados (apenas por exemplo) ... ter feito isso sem o mapa teria sido uma tarefa muito mais tediosa.
Concedido, ele é escrito em uma versão de JavaScript que não acho que muitos navegadores suportem ainda (pelo menos totalmente), mas - estamos chegando lá. Se eu precisasse rodar no navegador, acredito que transpilaria muito bem.
fonte