según tengo entendido, tanto la matriz como los objetos se pasan por referencia en función de la dirección de memoria, por lo que si creo otra variable y apunto a la matriz/objeto, y muto cualquiera de los valores, también se debe cambiar otro valor.
Sin embargo, no entiendo muy bien cómo funciona aquí. Estoy apuntando a array1 y modificando array1 para que quede vacío, ¿por qué el valor en anotherArray no cambia?
var array1 = [1,2,3,4,5,6,7]; // Created array var anotherArray = array1; // Referenced array1 by another variable array1 = []; // Empty the array console.log(anotherArray); // Output [1,2,3,4,5,6,7]
Puedo entender el ejemplo a continuación por qué anotherArray se vuelve [] vacío porque se pasa por referencia, pero ¿por qué anotherArray todavía genera [1,2,3,4,5,6,7] para lo anterior?
var array1 = [1,2,3,4,5,6,7]; // Created array var anotherArray = array1; // Referenced array1 by another variable array1.length = 0; // Empty the array by setting length to 0 console.log(anotherArray); // Output []
Gracias.
Asignar a una variable nunca cambia el objeto que la variable tenía previamente como valor.
Los objetos, como las matrices, solo cambian cuando los muta , ya sea llamando a un método que hace esto o configurando una propiedad.
Aquí hay una visualización de su primer script:
var array1 = [1,2,3,4,5,6,7]
da como resultado esto:
array1 ↓ ┌──────┬───┬───┬───┬───┬───┬───┬───┐ │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ ├──────┼───┼───┼───┼───┼───┼───┼───┤ │ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ └──────┴───┴───┴───┴───┴───┴───┴───┘
Después de var anotherArray = array1
tenemos esto:
array1 ↓ ┌──────┬───┬───┬───┬───┬───┬───┬───┐ │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ ├──────┼───┼───┼───┼───┼───┼───┼───┤ │ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ └──────┴───┴───┴───┴───┴───┴───┴───┘ ↑ anotherArray
Entonces array1 = []
creará una nueva matriz: ahora hay dos matrices. También hace que array1
sea una referencia para la matriz recién creada:
array1 ↓ ┌──────┐ │length│ ├──────┤ │ 0 │ └──────┘ ┌──────┬───┬───┬───┬───┬───┬───┬───┐ │length│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ ├──────┼───┼───┼───┼───┼───┼───┼───┤ │ 7 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ └──────┴───┴───┴───┴───┴───┴───┴───┘ ↑ anotherArray
En el segundo script, la asignación a la propiedad de length
(en realidad, un setter) mutará la matriz. No se crea una nueva matriz y los valores 1,2,3,4,5,6,7 se pierden:
array1 ↓ ┌──────┐ │length│ ├──────┤ │ 0 │ └──────┘ ↑ anotherArray
Para su primer ejemplo, en realidad está haciendo una reasignación a matriz1 como una matriz vacía (y ahora apuntan a 2 matrices diferentes en la memoria), por lo tanto, la otra matriz permanece sin cambios.
var array1 = [1,2,3,4,5,6,7]; // Created array var anotherArray = array1; // Referenced array1 by another variable array1 = []; // Empty the array console.log(anotherArray); // Output [1,2,3,4,5,6,7]
En este caso, en realidad está modificando la matriz asignando su longitud a 0. dado que array1 se refiere a ella, también lo afecta, ya que se refieren a la misma matriz en la memoria.
var array1 = [1,2,3,4,5,6,7]; // Created array var anotherArray = array1; // Referenced array1 by another variable array1.length = 0; // Empty the array by setting length to 0 console.log(anotherArray); // Output []
La línea
array1 = [];
no modifica el objeto de matriz previamente asignado a array1
. Asigna una nueva matriz (vacía) a la variable; no es como invocar una operación en el objeto asignado a array1
.
Para explicarlo en otras palabras, suponga que array1
era la única variable que hacía referencia al objeto de matriz previamente asignado ( [1,2,3,4,5,6,7]
). Tras la ejecución de esa línea (que es una declaración, por cierto), se perdió la matriz previamente asignada; y sería basura recolectada algún tiempo después. Todo esto se debe a que el operador de asignación se usa aquí y la forma en que su semántica operativa se define en JavaScript.
Además, está haciendo un mal uso del concepto de paso por referencia aquí (también conocido como llamada por referencia ); que es un concepto que se relaciona con cómo se pasan los valores a los argumentos de las llamadas a funciones (o subrutinas/procedimientos, si prefiere hablar de subrutinas/procedimientos en lugar de funciones).