Introducción: ¿Por qué la copia normal no funciona?
\n\nImagina: estás escribiendo una aplicación que procesa una configuración compleja de usuario. Haces const newConfig = oldConfig, cambias un par de campos — y de repente el objeto original también cambia. ¿Un dolor familiar? 👋
En JavaScript, los objetos se pasan por referencia. Esto significa que una simple operación de asignación no crea un nuevo objeto, sino que solo copia el puntero al antiguo. De ahí surge la pregunta principal que atormenta a miles de desarrolladores en Stack Overflow: "What is the most efficient way to deep clone an object in JavaScript?".
\n\nEn este artículo analizaremos todas las formas populares de copia profunda, sus ventajas, desventajas y rendimiento. Aprenderás qué método elegir para 2024 y cómo escribir tu propio deep clone confiable.
\n\n¿Por qué hablamos de copia profunda?
\n\nLa copia profunda (deep clone) crea una copia completamente independiente del objeto con todas las estructuras anidadas. A diferencia de la copia superficial (shallow copy), donde los objetos anidados permanecen compartidos.
\n\nAquí hay un escenario típico donde se necesita:
\n- \n
- Trabajo con Redux / Zustand: no se puede mutar el estado, hay que crear copias. \n
- Serialización de datos para enviar al servidor. \n
- Trabajo con caché o configuraciones que no se pueden modificar. \n
- Pruebas unitarias: para no afectar los datos originales. \n
Pero no todo es tan sencillo. Si intentas copiar un objeto con funciones, undefined, Symbol o referencias circulares — muchos métodos fallarán o perderán datos. Analicemos cada método en detalle.
Método 1: JSON.parse(JSON.stringify(obj)) — viejo, pero funcional
\n\nEsta es la forma más popular entre los principiantes. Es simple y rápida de escribir:
\n\nconst original = {\n name: "Ana",\n age: 25,\n address: { city: "Moscú", zip: 101000 },\n hobbies: ["lectura", "correr"]\n};\n\nconst clone = JSON.parse(JSON.stringify(original));\n\nclone.address.city = "San Petersburgo";\nconsole.log(original.address.city); // "Moscú" — ✅ ¡la copia es independiente!\n\n\nVentajas:
\n- \n
- 🔥 Sintaxis muy simple. \n
- 🔥 Funciona para la mayoría de casos simples. \n
Desventajas (¡críticas!):
\n- \n
- ❌ Pierde funciones — se convierten en
undefined. \n - ❌ Pierde undefined — los campos con valor
undefineddesaparecen. \n - ❌ Pierde Symbol — las claves de tipo símbolo se pierden. \n
- ❌ No funciona con referencias circulares — lanza un error
TypeError. \n - ❌ Problemas con fechas —
Datese convierte en cadena. \n - ❌ Problemas con Map, Set, RegExp — se convierten en objetos vacíos. \n
Conclusión: Solo es adecuado para datos que sean garantizadamente serializables en JSON (cadenas, números, arrays, objetos simples).
\n\nMétodo 2: Structured Clone API — estándar moderno (2024)
\n\nA partir de 2022, JavaScript cuenta con una forma nativa de copia profunda — structuredClone. Está disponible en todos los navegadores modernos y Node.js 17+.
const clone = structuredClone(original);\n\nclone.address.city = "Kazán";\nconsole.log(original.address.city); // "Moscú" — ✅\n\n\nQué puede hacer structuredClone:
\n- \n
- ✅ Referencias circulares — ¡funciona! \n
- ✅ Fechas — conserva el tipo
Date. \n - ✅ Map y Set — copia correctamente. \n
- ✅ RegExp — también funciona. \n
- ✅ ArrayBuffer y Ty