Clonado de datos mutables o no primitivos

Ahora veremos varias formas de clonar objetos y arrays con problemas de mutación.

// Partimos del siguiente código:
const p1 = {
  nombre: "Xurxo",
  domicilio: {
    numero: "1",
    calle: "Celso Emilio Ferreiro",
  },
  titulos: [
    {
      id: 1,
      titulo: 'Filología clásica'
    },
    {
      id: 2,
      tituto: 'DAW'
    }
  ]
}

Object.assign({}, object)

[⚠️] Problemas de anidamiento

const p2 = Object.assign({},p1);
p2.nombre = 'David';
p2.domicilio.numero = "2";
p2.domicilio.calle = "Calle del Percebe";
console.log(p1, p2)

Salida

{
  nombre: 'Xurxo',
  domicilio: { numero: '2', calle: 'Calle del Percebe' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
} {
  nombre: 'David',
  domicilio: { numero: '2', calle: 'Calle del Percebe' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
}

Destructuring

[⚠️] Problemas de anidamiento

const p2 = {...p1};
p2.nombre = "David";
p2.domicilio.calle="Desconocido";
console.log(p1, p2)

Salida

{
  nombre: 'Xurxo',
  domicilio: { numero: '1', calle: 'Desconocido' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
} {
  nombre: 'David',
  domicilio: { numero: '1', calle: 'Desconocido' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
}

JSON.parse

[🗒️] Resolvemos el anidamiento sin librería externa

const p2 = JSON.parse(JSON.stringify(p1));
p2.nombre = "David";
p2.domicilio.numero = "2";
p2.domicilio.calle = "Desconocido";
console.log(p1, p2)

Salida

{
  nombre: 'Xurxo',
  domicilio: { numero: '1', calle: 'Celso Emilio Ferreiro' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
} {
  nombre: 'David',
  domicilio: { numero: '2', calle: 'Desconocido' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
}

Utilizando una librería externa

[!NOTE] Resolvemos el anidamiento con una librería como lodash

import * as _ from 'lodash';
const p2 = _.cloneDeep(p1);
p2.nombre = 'David';
p2.domicilio.numero = "2";
p2.domicilio.calle = "Desconocido";
console.log(p1, p2)

Salida

{
  nombre: 'Xurxo',
  domicilio: { numero: '1', calle: 'Celso Emilio Ferreiro' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
} {
  nombre: 'David',
  domicilio: { numero: '2', calle: 'Desconocido' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
}

structuredClone()

[!NOTE] La forma más eficaz

const p2 = structuredClone(p1)
p2.nombre = 'David';
p2.domicilio.numero = "2";
p2.domicilio.calle = "Desconocido";
console.log(p1, p2)

Salida

{
  nombre: 'Xurxo',
  domicilio: { numero: '1', calle: 'Celso Emilio Ferreiro' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
} {
  nombre: 'David',
  domicilio: { numero: '2', calle: 'Desconocido' },
  titulos: [
    { id: 1, titulo: 'Filología clásica' },
    { id: 2, titulo: 'DAW' }
  ]
}

Bibliografía