exemplo:
var arr = ["one","two","three"];
arr.forEach(function(part){
part = "four";
return "four";
})
alert(arr);
A matriz ainda está com seus valores originais; existe alguma maneira de ter acesso de gravação aos elementos da matriz a partir da função de iteração?
x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
Respostas:
O retorno de chamada é passado para o elemento, o índice e a própria matriz.
editar - conforme observado em um comentário, a
.forEach()
função pode usar um segundo argumento, que será usado como o valor dethis
em cada chamada para o retorno de chamada:Esse segundo exemplo mostra
arr
-se configurado comothis
no retorno de chamada. Alguém pode pensar que a matriz envolvida na.forEach()
chamada possa ser o valor padrão dethis
, mas por qualquer motivo, não;this
seráundefined
se esse segundo argumento não for fornecido.(Nota: o material acima
this
não se aplica se o retorno de chamada for uma=>
função, porquethis
nunca estará vinculado a nada quando essas funções forem chamadas.)Também é importante lembrar que existe toda uma família de utilitários semelhantes no protótipo Array, e muitas perguntas surgem no Stackoverflow sobre uma função ou outra, de modo que a melhor solução é simplesmente escolher uma ferramenta diferente. Você tem:
forEach
por fazer algo com ou para cada entrada em uma matriz;filter
por produzir uma nova matriz contendo apenas entradas qualificadas;map
para criar uma nova matriz individual transformando uma matriz existente;some
verificar se pelo menos um elemento em uma matriz se encaixa em alguma descrição;every
verificar se todas as entradas em uma matriz correspondem a uma descrição;find
procurar um valor em uma matrize assim por diante. Link MDN
fonte
part
(ou mesmoo
em es6) é indefinido? como obter valor iterado?part
seriaundefined
se um elemento da matriz fosse atribuídoundefined
explicitamente. Os slots "vazios" de uma matriz (uma entrada da matriz que nunca recebeu nenhum valor) são ignorados pela.forEach()
maioria dos outros métodos de iteração da matriz..forEach()
também é necessário um segundo argumentothisArg
, que você pode usar comothis
dentro do retorno de chamada. NOTA: este é um argumento de.forEach
NÃO um argumento do retorno de chamada.this
passado como segundo argumento para.forEach()
, você precisa passar a função de retorno de chamada usando a sintaxefunction()
, pois o uso da função de seta do ES6() => {}
não vincula o contexto.Vamos tentar simplificar e discutir como está realmente funcionando. Tem a ver com tipos de variáveis e parâmetros de função.
Aqui está o seu código que estamos falando:
Primeiro, aqui é onde você deve ler sobre Array.prototype.forEach ():
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Segundo, vamos falar brevemente sobre os tipos de valor em JavaScript.
Primitivas (indefinidas, nulas, String, Boolean, Number) armazenam um valor real.
ex:
var x = 5;
Os tipos de referência (objetos personalizados) armazenam a localização da memória do objeto.
ex:
var xObj = { x : 5 };
E terceiro, como os parâmetros de função funcionam.
Nas funções, os parâmetros são sempre passados por valor.
Como
arr
é uma matriz de Strings, é uma matriz de objetos primitivos , o que significa que eles são armazenados por valor.Portanto, para o seu código acima, isso significa que toda vez que o forEach () itera,
part
é igual ao mesmo valor quearr[index]
, mas não o mesmo objeto .part = "four";
mudará apart
variável, mas deixará emarr
paz.O código a seguir alterará os valores que você deseja:
Agora, se a matriz
arr
for uma matriz de tipos de referência , o código a seguir funcionará porque os tipos de referência armazenam um local de memória de um objeto em vez do objeto real.A seguir, ilustra que você pode alterar
part
para apontar para um novo objeto enquanto deixa os objetos armazenadosarr
sozinhos:fonte
In functions, parameters are always passed by value.
e o segundo exemplo?Matriz:
[1, 2, 3, 4]
Resultado:
["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
Manter matriz originalArray.prototype.forEach()
Substituir matriz originalfonte
let arr1 = ["1", 2, 3, 4]; arr1.map(function(v) { return "foo"+ v; }); console.log( arr );
Array.prototype.map () Nunca modifique a matriz original, para cada mutação.map
definitivamente pode alterar sua matriz eforEach
, em geral, não.Javascript é transmitido por valor, e o que essencialmente significa
part
é uma cópia do valor na matriz.Para alterar o valor, acesse a própria matriz no seu loop.
arr[index] = 'new value';
fonte
part
se ele é copiado - embora você está certo de que a variável não é um ponteiro, mas um valorsubstitua-o pelo índice da matriz.
fonte
Aqui está uma resposta semelhante usando uma
=>
função de estilo:dá o resultado:
O
self
parâmetro não é estritamente necessário com a função de estilo de seta, portantotambém funciona.
fonte
A função .forEach pode ter uma função de retorno de chamada (eachelement, elementIndex). Então, basicamente, o que você precisa fazer é:
Ou, se você quiser manter a matriz original, poderá fazer uma cópia antes de executar o processo acima. Para fazer uma cópia, você pode usar:
fonte
map()
vez deforEach()
.map()
itera sobre a matriz de origem e retorna uma nova matriz contendo a cópia [modificada] do original: a matriz de origem permanece inalterada.Com os métodos de objeto Array, você pode modificar o conteúdo da matriz e, em comparação com o básico para loops, esses métodos não possuem uma funcionalidade importante. Você não pode modificar o índice em execução.
Por exemplo, se você remover o elemento atual e colocá-lo em outra posição de índice na mesma matriz, poderá fazê-lo facilmente. Se você mover o elemento atual para uma posição anterior, não haverá problema na próxima iteração, o próximo item será o mesmo, como se você não tivesse feito nada.
Considere esse código em que movemos o item na posição 5 do índice para a posição 2 quando o índice conta até 5.
No entanto, se movermos o elemento atual para algum lugar além da posição atual do índice, as coisas ficam um pouco confusas. Em seguida, o item seguinte mudará para a posição de itens movidos e, na próxima iteração, não poderemos vê-lo ou avaliá-lo.
Considere este código em que movemos o item na posição 5 do índice para a posição 7, depois que o índice conta até 5.
Portanto, nunca encontramos 6 no circuito. Normalmente, em um loop for, é esperado que você diminua o valor do índice ao mover o item da matriz para frente, para que o índice permaneça na mesma posição na próxima execução e você ainda possa avaliar o item deslocado para o lugar do item removido. Isso não é possível com métodos de matriz. Você não pode alterar o índice. Verifique o seguinte código
Como você vê quando diminuímos,
i
ele não continuará de 5, mas 6, de onde foi deixado.Portanto, mantenha isso em mente.
fonte
Para adicionar ou excluir completamente elementos que alterariam o índice, por meio da extensão da sugestão zhujy_8833 de slice () para iterar sobre uma cópia, basta contar o número de elementos que você já excluiu ou adicionou e alterou o índice de acordo. Por exemplo, para excluir elementos:
Para inserir elementos antes:
Para inserir elementos após:
Para substituir um elemento:
Nota: se implementar inserções 'antes' e 'depois', o código deve manipular 'antes' as inserções primeiro, o contrário não seria o esperado
fonte
Você pode tentar isso se quiser substituir
fonte