Hamburger Icon
JavaScript: clona objetos like a boss con structuredClone

JavaScript: clona objetos like a boss con structuredClone

Los replicantes, en un principio, fueron concebidos para realizar trabajos pesados que no queríamos hacer. Con el tiempo se fueron mejorando y cada vez se parecían más al ser humano.

En cierto momento, se creó al robot humanoide Nexus 6. Eran indistinguibles de nosotros, pero la aparienza es embustera. Eran mucho más fuertes y ágiles. Nos iban a dar una buena.

Te estoy hablando de Blade Runner, como quizá ya te hayas dado cuenta. En este post te voy a explicar cómo dejar de hacer clones JavaScript equivalentes al apestoso Nexus 1, para pasar a hacer clones como el maravilloso Nexus 6.

El clonado de objetos en JavaScript siempre ha dado que hablar. Poco a poco esto va mejorando y, aunque todavía no es perfecto, hemos dado un paso más con structuredClone.

Tipos de clonado

Antes de ponernos manos a la obra, quizá sea bueno definir antes un par de conceptos.

En JavaScript es posible hacer copias superficiales de los objetos, también conocidas como shallow copies. Este tipo de copias es la más habitual e implica que, los cambios hechos en objetos anidados, se replican en el objeto original.

Ejemplo:

const original = {
  clave1: "lorem ipsum",
  clave2: {
    subclave1: "hola mundo",
    subclave2: "Blade Runner mola",
  },
}

// hacemos una copia superficial
const replicante = { ...original }

// si añadimos una subclave nueva en el replicante...
replicante.clave2.subclave3 = "Oops"

// esta propiedad también estará presente en el original:
console.log(original.clave2.subclave3) // "Oops"

En cambio, con las copias profundas o deep copies conseguimos que el objeto que replicamos sea totalmente independiente del original.

Usando Javascript structuredClone

No te creas que va a ser difícil. Para nada:

const original = {
  clave1: "lorem ipsum",
  clave2: {
    subclave1: "hola mundo",
    subclave2: "Blade Runner mola",
  },
}

const copia = structuredClone(original)

Ahí lo tienes. Ya has conseguido una copia profunda que puede ser modificada sin miedo a cargarnos algo en el objeto original.

Ya teníamos alternativas, pero con inconvenientes

En el primer ejemplo has visto cómo se ha hecho una copia mediante el spread del objeto original y lo que sucede si modificamos objetos anidados en la copia.

Otra forma es esta:

const copia = JSON.parse(JSON.stringify(original))

Esta copia es un poco mejor, pero si el objeto original tiene una estructura de datos recursiva te va a dar error, igual que si tienes datos en tipos nativos como una fecha o una expresión regular, y por supuesto, funciones. Todo eso te generaría un error al hacer la copia. Puedes ver más ejemplos en este post.

Por otro lado, mediante la librería Lodash hay disponible el método cloneDeep, que funciona a la perfección, pero ya es necesario añadir una dependencia más al proyecto.

Qué puedes clonar y qué no con structuredClone

No puedes clonar:

  • Funciones
  • nodos del DOM
  • getters y setters
  • prototipos

Si no necesitas clonar nada de eso, genial, porque por lo demás, no hay problema. Podrás clonar objetos que contengan tipos nativos como booleanos, fechas, etc.

Conclusión

Con structuredClone puedes hacer copias profundas de objetos de forma fácil. Poco a poco vamos mejorando. El siguiente paso ya será hacer una copia perfecta, seguro que en un tiempo lo tenemos. Esperemos que no nos salga rana, como el Nexus 6...

Si te apetece, puedes continuar destripando JavaScript.