Aquí hay un ejemplo de la consola del navegador.
a=[[1,2,3],[3,2,1]] b=[] b.push(a) a[0][0]=9 b.push(a)
En ese caso, esperaba que b fuera
[[[1,2,3],[3,2,1]],[[9,2,3],[3,2,1]]]
Pero será
[[[9,2,3],[3,2,1]],[[9,2,3],[3,2,1]]]
Adjunto una captura de pantalla para mostrar mejor los resultados en el navegador: consola de navegadores con el mismo código que arriba y salida
¿Alguna idea sobre por qué sucede esto y cómo llegar a mis resultados esperados?
En JavaScript, los objetos se pasan por referencia, lo que significa que las "copias" no son copias. Apuntan a la misma dirección en la RAM, por lo que mutar una referencia las muta a todas.
Para aplicar a este caso, si aún no lo sabía, las matrices son tipos especiales de objetos . Para probar esto, puede ejecutar typeof []
en la consola de su navegador. Eso significa que las matrices heredan el comportamiento de "pasar por referencia", lo que significa que si let c = a
luego ejecuta c[0] = 1
, a
también cambiará y viceversa.
Para resolver este problema, puede usar Array.prototype.slice
:
const a = [[1, 2, 3], [3, 2, 1]]; const b = []; Array.prototype.pushWithoutReference = function(add) { for(let i = 0; i < add.length; i++) { this[this.length] = add[i].slice(0); } } b.pushWithoutReference(a); a[0][0] = 9; b.pushWithoutReference(a);
Para el lenguaje en sí, no hay arreglos multidimensionales, hay otros arreglos dentro de un arreglo. No importa si contiene matrices, objetos simples, funciones o primitivas. Para las primitivas, se copiarán sus valores. De lo contrario, se copiarán las referencias a los objetos.
Puede hacerlo empujando las copias de las matrices internas de la matriz a
con la ayuda de map
y spread operator(...)
.
var a=[[1,2,3],[3,2,1]]; var b=[]; b.push(a.map(x=>[...x])); a[0][0]=9; b.push(a); console.log(b);
Ok, según todos los comentarios aquí, especialmente el de @code, y también otra publicación ( ¿Cómo paso el valor en lugar de la referencia de una matriz? ) Pude lograr los resultados usando esto:
b.push([]); for(line of a){ b[b.length-1].push(a.slice(0)); }
EDITAR
La sugerencia de Abhijeet también funciona perfectamente:
b.push(a.map(x=>[...x]));