JavaScript

Cómo clonar (copiar) objetos y arrays en JavaScript

Last updated: 21.02.2026
Views: 87
La clonación de objetos y arrays no es un tema tan sencillo como puede parecer a primera vista. La clonación de objetos y matrices en JavaScript se puede realizar mediante distintos métodos según la complejidad (clonación superficial o profunda).

Clonación de un array

1. Uso del operador spread (...):

const originalArray = [1, 2, 3];
const clonedArray = [...originalArray];
console.log(clonedArray); // Output: [1, 2, 3]

2. Uso de Array.prototype.slice():

const originalArray = [1, 2, 3];
const clonedArray = originalArray.slice();
console.log(clonedArray); // Output: [1, 2, 3]

3. Uso de Array.from():

const originalArray = [1, 2, 3];
const clonedArray = Array.from(originalArray);
console.log(clonedArray); // Output: [1, 2, 3]

4. Uso de structuredClone() (clonación profunda):

const originalArray = [1, { key: "value" }];
const clonedArray = structuredClone(originalArray);
console.log(clonedArray); // Output: [1, { key: "value" }]

Clonación de un objeto

1. Uso del operador spread (...):

const originalObject = { a: 1, b: 2 };
const clonedObject = { ...originalObject };
console.log(clonedObject); // Output: { a: 1, b: 2 }

2. Using Object.assign():

const originalObject = { a: 1, b: 2 };
const clonedObject = Object.assign({}, originalObject);
console.log(clonedObject); // Output: { a: 1, b: 2 }

3. Uso de structuredClone() (clonación profunda):

const originalObject = { a: 1, b: { c: 2 } };
const clonedObject = structuredClone(originalObject);
console.log(clonedObject); // Output: { a: 1, b: { c: 2 } }

4. Uso de JSON.parse() y JSON.stringify() (clonación profunda):

const originalObject = { a: 1, b: { c: 2 } };
const clonedObject = JSON.parse(JSON.stringify(originalObject));
console.log(clonedObject); // Output: { a: 1, b: { c: 2 } }

Este método no admite funciones, undefined, Symbol o referencias circulares.
Clonación profunda vs. clonación superficial

  • Clonación superficial (p. ej., utilizando ..., slice() o Object.assign()):
    Solo clona el primer nivel del objeto u array. Los objetos u arrays anidados siguen siendo referencias al original.
  • Clonación profunda (p. ej., structuredClone() o JSON.parse(JSON.stringify())):
    Clona toda la estructura, incluidos los arrays u objetos anidados.

Cuándo utilizar cada método

  • Utilice la clonación superficial para estructuras simples y planas.
  • Utilice la clonación profunda si el objeto u array contienen estructuras anidadas y necesita evitar referencias a los datos originales.

Clonación de un array o de un objeto que contiene métodos (funciones)

Clonación superficial

Uso del operador de propagación (...) u Object.assign()

  • Las funciones en el objeto u array se tratan como cualquier otra propiedad.
  • La referencia a la función se copia al objeto o matriz clonados.
  • Las versiones original y clonada compartirán la misma función en la memoria.
const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};
const clonedObject = { ...originalObject };

console.log(clonedObject.method()); // Output: 42
console.log(clonedObject.method === originalObject.method); // Output: true (same reference)

Para arrays: si la matriz contiene funciones, se copian las referencias a esas funciones. Uso del operador de propagación (...) o slice()

const originalArray = [1, 2, function () { return 42; }];
const clonedArray = [...originalArray];

console.log(clonedArray[2]()); // Output: 42
console.log(clonedArray[2] === originalArray[2]); // Output: true (same reference)

Clonación profunda

Uso de JSON.parse(JSON.stringify())

  • Los métodos (funciones) se perderán porque JSON solo admite tipos de datos serializables (por ejemplo, números, cadenas, matrices y objetos).
  • Cualquier propiedad que contenga funciones no existirá en el objeto o array clonado.
const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};
const clonedObject = JSON.parse(JSON.stringify(originalObject));

console.log(clonedObject.method); // Output: undefined

Uso de structuredClone() (clonación profunda)
Las funciones no se clonan. La clonación estructurada no admite funciones y las eliminará del objeto o array clonado.

const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};
const clonedObject = structuredClone(originalObject);

console.log(clonedObject.method); // Output: undefined

Puntos clave para recordar

1. Clonación superficial:

  • Las funciones se copian por referencia, lo que significa que los objetos/arrays clonados y originales compartirán la misma función.

2. Clonación profunda:

  • Las funciones generalmente se pierden (eliminan) cuando se usan métodos como JSON.parse(JSON.stringify()) o structuredClone() porque no son serializables.

3. Si necesita clonar un objeto o array con métodos, es posible que deba escribir una función de clonación personalizada para manejar las funciones explícitamente o usar bibliotecas de terceros.

Clonación personalizada para objetos con métodos

Puede manejar funciones manualmente en su lógica de clonación:

function customClone(obj) {
    const clone = Array.isArray(obj) ? [] : {};
    for (const key in obj) {
        if (typeof obj[key] === 'function') {
            clone[key] = obj[key]; // Copy functions by reference
        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
            clone[key] = customClone(obj[key]); // Recursively clone objects
        } else {
            clone[key] = obj[key]; // Copy primitives
        }
    }
    return clone;
}

const original = {
    value: 42,
    method() {
        return this.value;
    }
};

const cloned = customClone(original);

console.log(cloned.method()); // Output: 42
console.log(cloned.method === original.method); // Output: true (same reference)

Este enfoque garantiza que se conserven las funciones mientras se clonan profundamente otras propiedades.

Uso de bibliotecas de terceros

En los proyectos, suelo utilizar Lodash o jQuery. Ambas bibliotecas tienen métodos de clonación profunda. Cuando se utiliza Lodash o jQuery para realizar una clonación profunda, ambas bibliotecas tratan las funciones de forma diferente a los métodos nativos como JSON.parse(JSON.stringify()) o structuredClone().

Clonación profunda con Lodash

Uso de _.cloneDeep() de Lodash:

  • Lodash realiza una clonación profunda del objeto o array, incluidas las estructuras anidadas.
  • Las funciones (métodos) en el objeto o array se copian por referencia. Esto significa que la función en el objeto clonado o array apuntará a la misma referencia de memoria que el original.
const _ = require('lodash');

const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};

const clonedObject = _.cloneDeep(originalObject);

console.log(clonedObject.method()); // Output: 42
console.log(clonedObject.method === originalObject.method); // Output: true (same reference)

Lodash no elimina funciones, a diferencia de JSON.parse(JSON.stringify()), pero no crea una nueva copia de la función. Conserva una referencia a la original.

Clonación profunda con jQuery

Uso de $.extend() de jQuery:

  • Se utiliza $.extend() de jQuery para clonar objetos. Para lograr una clonación profunda, se pasa true como primer argumento.
  • Al igual que Lodash, jQuery copia funciones por referencia.
const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};

const clonedObject = $.extend(true, {}, originalObject);

console.log(clonedObject.method()); // Output: 42
console.log(clonedObject.method === originalObject.method); // Output: true (same reference)

Limitaciones de $.extend():

  • El mecanismo de clonación de jQuery es más simple y menos robusto en comparación con Lodash.
  • No maneja algunos casos de uso avanzados (por ejemplo, referencias circulares) con tanta eficiencia como Lodash.
author
Autor: Igor Rybalko
He estado trabajando como desarrollador front-end desde 2014. Mi principal pila tecnológica es Vue.js y WordPress.

Publicaciones similares:

Leave a Reply

Your email address will not be published. Required fields are marked *