preloader

Referencias de Objetos y Copia

Referencias de Objetos y Copia

Una distinción fundamental entre objetos y tipos primitivos es cómo se almacenan y copian en JavaScript. Los tipos primitivos como strings, números y booleanos se asignan y copian como valores completos, mientras que los objetos se almacenan y copian por referencia, es decir, se maneja la dirección de memoria del objeto en lugar de su valor directo.

Empecemos con un ejemplo utilizando un tipo primitivo, como un string:

				
					let message = "Hola!";
let phrase = message;

				
			

Aquí, phrase contiene una copia independiente del valor "Hola!", sin conexión directa con message.

En contraste, los objetos se manejan de manera diferente. Una variable que almacena un objeto no guarda el objeto en sí, sino una referencia que apunta a su ubicación en la memoria:

				
					let user = {
  name: "Juan"
};

				
			

En este caso, user contiene una referencia al objeto almacenado en la memoria.

Cuando se copia una variable que contiene un objeto, solo se copia la referencia al objeto, no el objeto en sí mismo:

				
					let admin = user; // copia la referencia al mismo objeto

				
			

Ahora tanto user como admin apuntan al mismo objeto en la memoria.

Si modificamos el objeto a través de cualquiera de las referencias, los cambios se reflejan en todas las referencias que apuntan a ese objeto:

				
					admin.name = 'Pedro'; // cambia el objeto a través de la referencia "admin"
console.log(user.name); // 'Pedro', los cambios son visibles a través de la referencia "user" también

				
			

Esto se asemeja a tener dos llaves que abren el mismo armario; los cambios realizados con una llave afectan el contenido que se ve al abrirlo con la otra llave.

Comparación por Referencia

Dos variables que contienen referencias a objetos son iguales solo si apuntan al mismo objeto en memoria:

				
					let a = {};
let b = a; // b contiene la misma referencia que a

console.log(a === b); // true, a y b apuntan al mismo objeto

				
			

En contraste, dos objetos independientes nunca son iguales, incluso si tienen las mismas propiedades:

				
					const user = {
  name: "Juan"
};

user.name = "Pedro"; // No hay error, las propiedades del objeto pueden cambiar

console.log(user.name); // "Pedro"

				
			

Para hacer que las propiedades del objeto también sean constantes, se necesitan métodos adicionales que discutiremos más adelante.

Clonación y Mezcla de Objetos

Para duplicar un objeto, podemos crear un nuevo objeto y copiar todas las propiedades del original:

				
					let user = {
  name: "Juan",
  age: 30
};

let clone = {};

for (let key in user) {
  clone[key] = user[key];
}

clone.name = "Pedro"; // Cambiamos datos en el objeto clonado

console.log(user.name); // "Juan", el objeto original no se ve afectado

				
			

También podemos usar Object.assign para una clonación superficial:

				
					let user = { name: "Juan" };
let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

Object.assign(user, permissions1, permissions2);

console.log(user.name); // "Juan"
console.log(user.canView); // true
console.log(user.canEdit); // true

				
			

Si las propiedades a copiar ya existen en el objeto destino, serán sobrescritas.

Clonación Profunda

Cuando un objeto contiene propiedades que son ellos mismos objetos (anidados), simplemente copiarlas no es suficiente, ya que se copian por referencia:

				
					let user = {
  name: "Juan",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = Object.assign({}, user);

console.log(user.sizes === clone.sizes); // true, comparten la misma referencia

				
			

Para realizar una clonación profunda, es necesario copiar recursivamente todos los objetos anidados. Esto asegura que el objeto clonado no comparta referencias con el original.

Clonación Estructurada

La función structuredClone(object) clona un objeto y todos sus objetos anidados de manera profunda:

				
					let user = {
  name: "Juan",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = structuredClone(user);

console.log(user.sizes === clone.sizes); // false, objetos diferentes

				
			

Este método maneja también referencias circulares de manera adecuada.

Related Post

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *