Estaba estudiando JS cuando me enfrenté a un comportamiento inesperado. Probablemente sea algo relacionado con el alcance local frente al global, sin embargo, no pude encontrar la respuesta. Aquí cómo va:
Tengo dos matrices, una vacía y otra con algunos valores. Si presiona el que tiene valores dentro del vacío, luego actualiza los valores usando el método .push() , también actualizará la matriz dentro del otro:
let newArr = []; let valueArr = [0,0]; newArr.push(valueArr); // newArr = [[0,0]] console.log(newArr); valueArr.push(0); // newArr = [0,0,0] --> updates it console.log(valueArr); Sin embargo, si ahora intenta actualizar la variable usando = asignación, no cambiará la matriz dentro newArr
let newArr = []; let valueArr = [0,0]; newArr.push(valueArr); // newArr = [[0,0]] console.log(newArr); valueArr = [0,0,0]; // newArr = [[0,0]] --> does not update it console.log(newArr); ¿Alguien sabe por qué empujar tiene este comportamiento y reasignar no? ¿Se debe al alcance local/global o cuando reasigno la variable valueArr , la variable newArr pierde su rastro?
Esto no está relacionado con el ámbito local/global.
TLDR
Cuando llama a push en una matriz, agrega elementos a la matriz existente. Cuando usa una asignación, crea una nueva matriz que no tiene nada que ver con la que estaba almacenada en la variable anteriormente.
Detallado
Esto es lo que está sucediendo en el código:
Paso 1. let valueArr = [0,0];
Cuando asigna una matriz a una variable, suceden dos cosas:
[0,0] )valueArr guarda una referencia a la matriz creada Paso 2. newArr.push(valueArr);
Luego, inserta la matriz valueArr en la matriz newArr . Ahora newArr[0] contiene un elemento con la misma referencia que valueArr . Ambos apuntan a la matriz [0,0] .
Paso 3. valueArr.push(0);
En este paso, empujamos un elemento a la matriz a la que hace referencia valueArr . Dado que newArr hace referencia a la misma matriz, newArr[0] también se actualiza.
Paso 4. valueArr = [0,0,0];
Aquí repetimos el paso 1. Crea una nueva matriz y guarda su referencia a valueArr . La cuestión es que cambiamos la referencia almacenada en valueArr , pero newArr[0] todavía apunta a la matriz anterior. Es por eso que no ve ninguna actualización: es una matriz completamente diferente.
Este sería un buen comienzo si desea obtener más información sobre los tipos de referencia: https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0
Si desea actualizar newArr , hágalo explícitamente:
valueArr = [0,0,0]; newArr[0] = valueArr;Debe distinguir entre un objeto y una referencia a un objeto . Un objeto es una "cosa". Pero una referencia a un objeto es solo una forma de describir de qué "cosa" estás hablando.
Una variable es una forma de hacer referencia explícita a un objeto mediante un nombre. Pero también puede hacer referencia a objetos de otras maneras, como (como descubrió) a través de un índice de matriz.
Un par de cosas importantes a tener en cuenta:
= ) crea explícitamente una referencia a un objeto. Más tarde puede hacer referencia a ese objeto a través del nombre de la variable.[ ] ) en el lado derecho del operador de asignación.a.push(b) crea implícitamente una referencia desde algún índice de a al objeto al que hace referencia b en ese momento.=== ) para determinar si dos expresiones se refieren al mismo objeto. /* We create a new array, lets call it Object 1. We can refer to that array using the variable name `a`. */ let a = []; /* We create a new array, lets call it Object 2. We refer to that array using the variable name `b`. */ let b = [0]; /* When we call `push` we are implicitly creating a new reference: from a[0] to Object 2. */ a.push(b); /* `a[0]` and `b` are both referring to the *exact same* object: Object 2. */ console.log("Are `a[0]` and `b` the same object:", a[0] === b); // -> true /* We create a new array, lets call it Object 3. We explicitly tell Javascript to use `b` to refer to Object 3 from this point forward. */ b = [2]; /* Notice that `a[0]` still refers to Object 2. */ console.log("Are `a[0]` and `b` the same object:", a[0] === b); // -> false /* We can explicitly tell javascript to update `a` by using the assignment operator. */ a[0] = b; console.log("Are `a[0]` and `b` the same object:", a[0] === b); // -> true