clonar-objetos-en-javascript

Clonar Objetos en JavaScript

Clonar un objeto implica crear una copia independiente que pueda modificarse sin afectar al objeto original.

Esto es especialmente importante porque en JavaScript todos objetos son tipos de referencia.

Es decir, que cuando asignas un objeto a una nueva variable, ambas variables apuntan al mismo objeto en memoria. Si modificas una, la otra también se verá afectada:

const original = { nombre: "Juan", edad: 25 };
const copia = original;

copia.nombre = "María";
console.log(original.nombre); // "María" (el objeto original también cambió)

Para evitar efectos colaterales no deseados, es necesario clonar objetos en lugar de simplemente copiar la referencia.

Para esta entrada, es muy importante que entendáis lo que es un tipo valor y un tipo referencia

Clonación superficial

La clonación superficial (shallow copy) crea una nueva instancia de un objeto y copia las propiedades de nivel superior.

Sin embargo, si alguna de estas propiedades es un objeto en sí, solo se copiará la referencia.

MétodoTipo de clonaciónAnidadasValores especialesComplejidad
Operador de propagaciónSuperficialBaja
Object.assign()SuperficialBaja

Usando el operador de spread ...

El operador de propagación (...) es una forma moderna y concisa de clonar un objeto. Este método crea una copia superficial del objeto, lo que significa que copia las propiedades de nivel superior, pero no los objetos o arrays anidados.

const original = { nombre: "Juan", edad: 25 };
const clon = { ...original };

clon.nombre = "María";
console.log(original.nombre); // "Juan" (el original no se modifica)

Sin embargo, si el objeto tiene propiedades anidadas, estas seguirán compartiendo referencias con el original:

const original = { nombre: "Juan", detalles: { edad: 25, ciudad: "Madrid" } };
const clon = { ...original };

clon.detalles.ciudad = "Barcelona";
console.log(original.detalles.ciudad); // "Barcelona" (se afecta el original)

Usando Object.assign()

Object.assign() es otra forma de realizar una clonación superficial. Este método copia las propiedades propias de un objeto (no las heredadas) al objeto de destino.

const original = { nombre: "Juan", edad: 25 };
const clon = Object.assign({}, original);

clon.nombre = "María";
console.log(original.nombre); // "Juan"

Al igual que el operador de propagación, este método no clona objetos anidados.

Clonación profunda

La clonación profunda (deep copy) crea una copia completa de un objeto, incluyendo todos los objetos anidados.

Esto asegura que las modificaciones en la copia no afecten al objeto original (es la clonación “de verdad”)

MétodoTipo de clonaciónAnidadasValores especialesComplejidad
structuredClone()ProfundaBaja
JSON.parse(JSON.stringify)ProfundaMedia
_.cloneDeep() (Lodash)ProfundaMedia
Clonación manualDependeDependeAlta

Usando structuredClone()

A partir de ES2021, JavaScript introdujo el método structuredClone, que permite realizar clonaciones profundas de manera nativa.

const original = { nombre: "Juan", detalles: { edad: 25, ciudad: "Madrid" } };
const clon = structuredClone(original);

clon.detalles.ciudad = "Barcelona";
console.log(original.detalles.ciudad); // "Madrid"

Limitaciones

  • No está disponible en versiones anteriores de JavaScript.
  • Puede no estar soportado en todos los navegadores.

Usando JSON

Una técnica sencilla para clonar objetos que no contienen métodos ni valores no serializables (como funciones, undefined, o propiedades circulares) es usar JSON.stringify() y JSON.parse().

const original = { nombre: "Juan", detalles: { edad: 25, ciudad: "Madrid" } };
const clon = JSON.parse(JSON.stringify(original));

clon.detalles.ciudad = "Barcelona";
console.log(original.detalles.ciudad); // "Madrid"

Limitaciones

  • No funciona si el objeto contiene funciones, valores undefined, o propiedades circulares.
  • Convierte valores especiales como Date a strings.

Usando bibliotecas externas

Cuando necesitas una solución robusta para clonar objetos complejos, puedes usar bibliotecas como Lodash. El método cloneDeep de Lodash realiza una clonación profunda completa.

import _ from "lodash";

const original = { nombre: "Juan", detalles: { edad: 25, ciudad: "Madrid" } };
const clon = _.cloneDeep(original);

clon.detalles.ciudad = "Barcelona";
console.log(original.detalles.ciudad); // "Madrid"

Clonación manual

En ciertos casos, especialmente si el objeto tiene estructuras específicas o necesitas optimizar el rendimiento, puedes clonar un objeto manualmente recorriendo sus propiedades.