ejemplo:
var arr = ["one","two","three"];
arr.forEach(function(part){
part = "four";
return "four";
})
alert(arr);
La matriz todavía tiene sus valores originales, ¿hay alguna forma de tener acceso de escritura a los elementos de la matriz desde la función iterativa?
x=[2,3,4]; x=x.map(n=>n*2); // [4,6,8]
Respuestas:
La devolución de llamada se pasa al elemento, el índice y la matriz en sí.
editar : como se indica en un comentario, la
.forEach()
función puede tomar un segundo argumento, que se usará como el valor dethis
en cada llamada a la devolución de llamada:Ese segundo ejemplo se muestra
arr
configurado comothis
en la devolución de llamada. Uno podría pensar que la matriz involucrada en la.forEach()
llamada podría ser el valor predeterminado dethis
, pero por alguna razón no lo es;this
seráundefined
si ese segundo argumento no se proporciona.(Nota: lo anterior
this
no se aplica si la devolución de llamada es una=>
función, porquethis
nunca está vinculada a nada cuando se invocan tales funciones).También es importante recordar que hay una familia completa de utilidades similares proporcionadas en el prototipo de matriz, y en Stackoverflow surgen muchas preguntas sobre una función u otra, de modo que la mejor solución es simplemente elegir una herramienta diferente. Tienes:
forEach
para hacer algo con o para cada entrada en una matriz;filter
para producir una nueva matriz que contenga solo entradas calificadas;map
para hacer una nueva matriz uno a uno transformando una matriz existente;some
para verificar si al menos un elemento de una matriz se ajusta a alguna descripción;every
para verificar si todas las entradas en una matriz coinciden con una descripción;find
buscar un valor en una matrizy así. Enlace MDN
fuente
part
(o inclusoo
en es6) no está definido? ¿Cómo obtener el valor iterado?part
seríaundefined
si un elemento de la matriz se ha asignadoundefined
explícitamente. Las ranuras "vacías" de una matriz (una entrada de matriz a la que nunca se le ha asignado ningún valor) se omiten.forEach()
y la mayoría de los otros métodos de iteración de matriz..forEach()
también toma un segundo argumentothisArg
, que puede usar comothis
dentro de la devolución de llamada. NOTA: este es un argumento de.forEach
NO un argumento de la devolución de llamada.this
pasado como segundo argumento.forEach()
, debe pasar la función de devolución de llamada utilizando la sintaxisfunction()
, ya que el uso de la función de flecha de ES6() => {}
no vincula el contexto.Vamos a tratar de mantener la sencillez y discutir la forma en que está trabajando realmente. Tiene que ver con tipos de variables y parámetros de función.
Aquí está su código del que estamos hablando:
En primer lugar, aquí es donde deberías leer sobre Array.prototype.forEach ():
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
En segundo lugar, hablemos brevemente sobre los tipos de valor en JavaScript.
Las primitivas (indefinido, nulo, cadena, booleano, número) almacenan un valor real.
ex:
var x = 5;
Los tipos de referencia (objetos personalizados) almacenan la ubicación de la memoria del objeto.
ex:
var xObj = { x : 5 };
Y tercero, cómo funcionan los parámetros de función.
En las funciones, los parámetros siempre se pasan por valor.
Debido a que
arr
es una matriz de cadenas, es una matriz de objetos primitivos , lo que significa que se almacenan por valor.Entonces, para su código anterior, esto significa que cada vez que forEach () itera,
part
es igual al mismo valor quearr[index]
, pero no el mismo objeto .part = "four";
cambiará lapart
variable, pero lo dejaráarr
solo.El siguiente código cambiará los valores que desee:
Ahora, si la matriz
arr
era una matriz de tipos de referencia , el siguiente código funcionará porque los tipos de referencia almacenan una ubicación de memoria de un objeto en lugar del objeto real.A continuación se ilustra que puede cambiar
part
para apuntar a un nuevo objeto mientras deja los objetos almacenadosarr
solos:fuente
In functions, parameters are always passed by value.
¿Qué pasa con el segundo ejemplo?Matriz:
[1, 2, 3, 4]
Resultado:
["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
Mantener matriz originalArray.prototype.forEach()
Anular matriz originalfuente
let arr1 = ["1", 2, 3, 4]; arr1.map(function(v) { return "foo"+ v; }); console.log( arr );
Array.prototype.map () Nunca modifique la matriz original, por cada mutación.map
definitivamente puede mutar su matriz yforEach
, en general, no lo hace.Javascript es pasar por valor, y lo que esencialmente significa
part
es una copia del valor en la matriz.Para cambiar el valor, acceda a la matriz en su bucle.
arr[index] = 'new value';
fuente
part
si se copia o no, aunque tiene razón en que la variable no es un puntero, sino un valorreemplácelo con el índice de la matriz.
fuente
Aquí hay una respuesta similar usando una
=>
función de estilo:da el resultado:
El
self
parámetro no es estrictamente necesario con la función de estilo de flecha, por lo queTambién funciona.
fuente
La función .forEach puede tener una función de devolución de llamada (eachelement, elementIndex) Entonces, básicamente, lo que debe hacer es:
O si desea conservar la matriz original, puede hacer una copia antes de realizar el proceso anterior. Para hacer una copia, puede usar:
fuente
map()
lugar deforEach()
.map()
itera sobre la matriz de origen y devuelve una nueva matriz que contiene la copia [modificada] del original: la matriz de origen no se modifica.Con los métodos de objeto Array puede modificar el contenido de Array comparado con el básico para bucles, estos métodos carecen de una funcionalidad importante. No puede modificar el índice en la ejecución.
Por ejemplo, si elimina el elemento actual y lo coloca en otra posición de índice dentro de la misma matriz, puede hacerlo fácilmente. Si mueve el elemento actual a una posición anterior, no hay problema en la próxima iteración, obtendrá el mismo elemento siguiente como si no hubiera hecho nada.
Considere este código donde movemos el elemento en la posición de índice 5 a la posición de índice 2 una vez que el índice cuenta hasta 5.
Sin embargo, si movemos el elemento actual a algún lugar más allá de la posición actual del índice, las cosas se complicarán un poco. Luego, el siguiente elemento cambiará a la posición de elementos movidos y en la próxima iteración no podremos verlo ni evaluarlo.
Considere este código donde movemos el elemento en la posición de índice 5 a la posición de índice 7 una vez que el índice cuenta hasta 5.
Entonces nunca hemos cumplido 6 en el ciclo. Normalmente, en un bucle for, se espera que disminuya el valor del índice cuando mueve el elemento de la matriz hacia adelante para que su índice permanezca en la misma posición en la próxima ejecución y aún pueda evaluar el elemento desplazado al lugar del elemento eliminado. Esto no es posible con los métodos de matriz. No puedes alterar el índice. Comprueba el siguiente código
Como ve cuando disminuimos
i
, no continuará desde 5 sino desde 6, desde donde se dejó.Así que ten esto en cuenta.
fuente
Para agregar o eliminar elementos completamente que alterarían el índice, mediante la extensión de la sugerencia zhujy_8833 de slice () para iterar sobre una copia, simplemente cuente el número de elementos que ya ha eliminado o agregado y modifique el índice en consecuencia. Por ejemplo, para eliminar elementos:
Para insertar elementos antes:
Para insertar elementos después de:
Para reemplazar un elemento:
Nota: si implementa las inserciones 'before' y 'after', el código debe manejar las inserciones 'before' primero, al revés no sería lo esperado
fuente
Puedes probar esto si quieres anular
fuente