Volver a la página principal
martes 16 julio 2024
17

Cómo clonar un objeto o un array en JavaScript

Clonación de Objetos

Clonación Superficial

La clonación superficial copia solo las propiedades de un objeto, pero no las referencias a otros objetos dentro de él. Esto significa que si el objeto contiene propiedades que son otros objetos, estas referencias seguirán apuntando a los mismos objetos después de la clonación.

Usando el Spread Operator

El spread operator (...) es una forma sencilla y moderna de realizar una clonación superficial de un objeto.

const original = { a: 1, b: 2, c: { d: 3 } };
const copia = { ...original };

console.log(copia); // { a: 1, b: 2, c: { d: 3 } }
console.log(copia.c === original.c); // true

Usando Object.assign()

Otra manera de realizar una clonación superficial es mediante el método Object.assign().

const original = { a: 1, b: 2, c: { d: 3 } };
const copia = Object.assign({}, original);

console.log(copia); // { a: 1, b: 2, c: { d: 3 } }
console.log(copia.c === original.c); // true

Clonación Profunda

La clonación profunda implica la copia de todas las propiedades, incluidas las referencias a otros objetos, de modo que las copias no compartan referencias con el objeto original.

Usando JSON

Una técnica común para la clonación profunda es convertir el objeto a una cadena JSON y luego volver a convertirlo a un objeto.

const original = { a: 1, b: 2, c: { d: 3 } };
const copia = JSON.parse(JSON.stringify(original));

console.log(copia); // { a: 1, b: 2, c: { d: 3 } }
console.log(copia.c === original.c); // false

Esta técnica tiene limitaciones, ya que no puede clonar funciones, fechas, undefined, y otros tipos de datos especiales.

Usando una Función Recursiva

Para una clonación profunda más completa, se puede implementar una función recursiva personalizada.

function clonarProfundo(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (Array.isArray(obj)) {
    const copia = [];
    for (let i = 0; i < obj.length; i++) {
      copia[i] = clonarProfundo(obj[i]);
    }
    return copia;
  }

  const copia = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copia[key] = clonarProfundo(obj[key]);
    }
  }
  return copia;
}

const original = { a: 1, b: 2, c: { d: 3 } };
const copia = clonarProfundo(original);

console.log(copia); // { a: 1, b: 2, c: { d: 3 } }
console.log(copia.c === original.c); // false

Esta función recursiva maneja arrays y objetos anidados correctamente.

Clonación de Arrays

Clonación Superficial

Usando el Spread Operator

El spread operator también puede utilizarse para clonar superficialmente arrays.

const original = [1, 2, { a: 3 }];
const copia = [...original];

console.log(copia); // [1, 2, { a: 3 }]
console.log(copia[2] === original[2]); // true

Usando Array.prototype.slice()

El método slice() crea una nueva copia superficial del array.

const original = [1, 2, { a: 3 }];
const copia = original.slice();

console.log(copia); // [1, 2, { a: 3 }]
console.log(copia[2] === original[2]); // true

Clonación Profunda

Usando JSON

La técnica de JSON puede aplicarse a arrays para lograr una clonación profunda.

const original = [1, 2, { a: 3 }];
const copia = JSON.parse(JSON.stringify(original));

console.log(copia); // [1, 2, { a: 3 }]
console.log(copia[2] === original[2]); // false

Usando una Función Recursiva

Podemos adaptar nuestra función recursiva para manejar arrays y objetos.

function clonarProfundo(obj) {
  if (obj === null || typeof obj !== 'object') {
    return obj;
  }

  if (Array.isArray(obj)) {
    const copia = [];
    for (let i = 0; i < obj.length; i++) {
      copia[i] = clonarProfundo(obj[i]);
    }
    return copia;
  }

  const copia = {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copia[key] = clonarProfundo(obj[key]);
    }
  }
  return copia;
}

const original = [1, 2, { a: 3 }];
const copia = clonarProfundo(original);

console.log(copia); // [1, 2, { a: 3 }]
console.log(copia[2] === original[2]); // false

Consideraciones Finales

La elección entre clonación superficial y profunda depende del contexto y de la naturaleza de los datos con los que se trabaja. La clonación superficial es rápida y suficiente para estructuras de datos simples, mientras que la clonación profunda es más adecuada para estructuras de datos complejas y anidadas.

Es crucial entender las limitaciones y el comportamiento de cada método para evitar errores y efectos secundarios no deseados en la manipulación de datos en aplicaciones JavaScript. Con las herramientas y técnicas adecuadas, se puede gestionar eficazmente la clonación de objetos y arrays para mantener la integridad de los datos y mejorar la robustez del código.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer