cambiar valores en la matriz al hacer foreach
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 de iteración?
A la devolución de llamada se le pasa el elemento, el índice y la matriz misma.
arr.forEach(function(part, index, theArray) {
theArray[index] = "hello world";
});
editar : como se indica en un comentario, la .forEach()
función puede tomar un segundo argumento, que se usará como valor de this
en cada llamada a la devolución de llamada:
arr.forEach(function(part, index) {
this[index] = "hello world";
}, arr); // use arr as this
Ese segundo ejemplo arr
se muestra configurado como this
en la devolución de llamada. Uno podría pensar que la matriz involucrada en la .forEach()
llamada podría ser el valor predeterminado de this
, pero por alguna razón no lo es; this
lo será undefined
si no se aporta ese segundo argumento.
(Nota: lo anterior this
no se aplica si la devolución de llamada es una =>
función, porque this
nunca está vinculada a nada cuando se invocan dichas funciones).
También es importante recordar que existe toda una familia de utilidades similares proporcionadas en el prototipo de Array, y surgen muchas preguntas en Stackoverflow 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 de una matriz;filter
para producir una nueva matriz que contenga sólo entradas calificadas;map
para crear una nueva matriz uno a uno transformando una matriz existente;some
comprobar si al menos un elemento de una matriz se ajusta a alguna descripción;every
comprobar si todas las entradas de una matriz coinciden con una descripción;find
buscar un valor en una matriz
etcétera. enlace MDN
Intentemos mantenerlo simple y discutir cómo funciona realmente. Tiene que ver con tipos de variables y parámetros de funciones.
Aquí está el código del que estamos hablando:
var arr = ["one","two","three"];
arr.forEach(function(part) {
part = "four";
return "four";
})
alert(arr);
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 valores en JavaScript.
Las primitivas (indefinida, nula, cadena, booleana, número) almacenan un valor real.
ex:var x = 5;
Los tipos de referencia (objetos personalizados) almacenan la ubicación de 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.
Como arr
es una matriz de cadenas, es una matriz de objetos primitivos , lo que significa que se almacenan por valor.
Entonces, para el código anterior, esto significa que cada vez que se itera forEach(), part
es igual al mismo valor que arr[index]
, pero no al mismo objeto .
part = "four";
Cambiará la part
variable, pero la dejará arr
sola.
El siguiente código cambiará los valores que desee:
var arr = ["one","two","three"];
arr.forEach(function(part, index) {
arr[index] = "four";
});
alert(arr);
Ahora bien, si la matriz arr
fuera 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.
var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];
arr.forEach(function(part, index) {
// part and arr[index] point to the same object
// so changing the object that part points to changes the object that arr[index] points to
part.num = "four";
});
alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
A continuación se ilustra que puede cambiar part
para que apunte a un nuevo objeto mientras deja los objetos almacenados arr
solos:
var arr = [{ num : "one" }, { num : "two"}, { num : "three"}];
arr.forEach(function(part, index) {
// the following will not change the object that arr[index] points to because part now points at a new object
part = 5;
});
alert(arr[0].num);
alert(arr[1].num);
alert(arr[2].num);
Matriz: [1, 2, 3, 4]
Resultado:["foo1", "foo2", "foo3", "foo4"]
Array.prototype.map()
Mantener la matriz original
const originalArr = ["Iron", "Super", "Ant", "Aqua"];
const modifiedArr = originalArr.map(name => `${name}man`);
console.log( "Original: %s", originalArr );
console.log( "Modified: %s", modifiedArr );
Array.prototype.map()
Anular la matriz original
let originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr = originalArr.map(name => `${name}man`);
console.log( "Original: %s", originalArr );
Array.prototype.forEach()
Anular la matriz original
const originalArr = ["Iron", "Super", "Ant", "Aqua"];
originalArr.forEach((name, index) => originalArr[index] = `${name}man`);
console.log( "Overridden: %s", originalArr );
Javascript se pasa 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';