84

Cómo copiar objetos en JavaScript sin morir en el intento

212939Puntos

hace 5 años

Decir que una variable es igual a otra variable NO es suficiente si trabajamos con Objetos en JavaScript. Cuando asignamos objetos a nuestras variables, en realidad, estamos asignando referencias a un espacio en memoria. No podemos utilizar los objetos como si fueran otro tipo de datos primitivos de JavaScript.

Los objetos merecen un trato especial y en este tutorial vamos a aprender a manejarlos como verdaderos profesionales del lenguaje.

Copiando cualquier otro tipo de datos en JavaScript

Supongamos que tenemos las siguientes variables:

let var1 = 1let var2 = var1

console.log(var1, var2) // 1, 1

Inicialmente, nuestra variable var2 tiene el mismo valor que la variable var1. Sin embargo, gracias a que utilizamos una variable de tipo let en vez de tipo const, podemos modificar el valor de cualquiera de nuestras variables sin afectar a las variables que copiamos anteriormente (sin sorpresas por ahora):

let var2 += 1console.log(var1, var2) // 1, 2

Así no funcionan los objetos 😛

Todo esto cambia cuando trabajamos con objetos.

Si queremos copiar los valores de un objeto a otras variables, en realidad, no copiamos los valores, sino la referencia al espacio en memoria que ocupan dichos objetos.

En otras palabras, cuando copiamos una variable de tipo objeto a, otras variables, no importa cuál de todas estas variables modifiquemos, en realidad, estamos modificando todas las variables con referencia a este mismo objeto:

let persona = {
        nombre: “Nombre por defecto”,
        edad: 0,
}

let juandc = persona
juandc.nombre = “Juan David”

console.log(juandc.nombre) // “Juan David”console.log(persona.nombre) // “Juan David” ???

Imagina todos los problemas que podemos encontrarnos por no saber cómo copiar nuestros objetos.

Utilizando Object.assign 😮

En vez de copiar los valores de nuestros objetos, cuando utilizamos el = lo que copiamos es la referencia a dicho objeto con sus respectivos valores.

Afortunadamente, JavaScript nos permite solucionar este problema utilizando la función Object.assign:

let persona = {
        nombre: “Nombre por defecto”,
        edad: 0,
}

let juandc = Object.assign({} , persona)
juandc.nombre = “Juan David”

console.log(juandc.nombre) // “Juan David”console.log(persona.nombre) // “Nombre por defecto”

Esta función SÍ copia los valores de nuestros objetos, no solo las referencias al objeto inicial.

Problemas de Object.assign 😭

¡Genial! Ahora que resolvimos el problemita de las copias podemos volver a programar como verdaderos profesionales. Pero no. No es suficiente. Aún tenemos problemas cuando nuestros objetos tienen, a su vez, subobjetos y más subobjetos:

let persona = {
nombre: “Nombre por defecto”,
edad: 0,
mascota: {
		nombre: “Mascota por defecto”,
		edad: 0,
}
}

let juandc = Object.assign({} , persona)
juandc.mascota.nombre = “Chacarron”

console.log(juandc.mascota.nombre) // “Chacarron”console.log(persona.mascota.nombre) // “Chacarron” ???????

JSON.parse y JSON.stringify al rescate 🙌

¡A prueba de errores y problemas de referencias! La respuesta definitiva para copiar objetos de JavaScript sin morir en el intento es utilizando las funciones JSON.stringify y JSON.parse.

La primera (JSON.stringify) se encarga de transformar los objetos en cadenas de texto mientras que, la segunda (JSON.parse) se encarga de transformar cadenas de texto en objetos.

Veamos un ejemplo:

let persona = {
nombre: “Nombre por defecto”,
edad: 0,
mascota: {
		nombre: “Mascota por defecto”,
		edad: 0,
}
}

let juandc = JSON.parse(JSON.stringify(persona))
juandc.mascota.nombre = “Chacarron”

console.log(juandc.mascota.nombre) // “Chacarron”console.log(persona.mascota.nombre) // “Mascota por defecto”!!

Conclusiones

Las copias de objetos (sin morir en el intento) son solo uno de los muchos temas que debemos aprender para dominar JavaScript. Gracias a este conocimiento podemos controlar mucho mejor otros conceptos como la abstracción, encapsulamiento, inmutabilidad y funciones puras.

Te invito a tomar los cursos de POO en JS para aprender a profundidad cómo funciona JavaScript por dentro para trabajar correctamente con este paradigma:

¡#NuncaParesDeAprender! 💚

Juan
Juan
juandc

212939Puntos

hace 5 años

Todas sus entradas
Escribe tu comentario
+ 2
Ordenar por:
17
10716Puntos

otra forma de copiar objetos es mediante el operador de propagacion

let juandc = {...persona}

aunque presenta los mismos “problemas” que Object.assign.

tambn funciona pa arrays

let la_gente = [...personas]

donde personas es un array.

2
11127Puntos
5 años

asi es , tiene los mismos problemas que Object.assign al momento de modificar sub-objetos, pero con JSON.parse y JSON.stringify se soluciona ese problema

0
12422Puntos
3 años

buena alternativa, aunque yo queria comentarla jajaja, pero no sabia que tenia los mismos problemas de Object.assign

4
13565Puntos

Buen articulo esto les aclarara las dudas a muchos 😃

3
9917Puntos

¿Cual es la diferencia entre el let, const y var?

solo se lo básico de javascript

1
9917Puntos
5 años

¡Gracias! a penas me acabo de dar cuenta de que me respondiste. Ahora pienso que platzi debería mejorar su sistema de notificaciones

2
13486Puntos

Excelente, hace poco pude solucionar un ejercicio con Object.assign, pero ahora veo que de complejizarse un poco más el ejercicio, me hubiera chocado contra la pared.
Excelente post, muchas gracias!!!

2
11950Puntos

Muy buena info
Tambien he visto que lo hacen con el spread operator

2
4161Puntos

No tenia idea de esta información, esta muy genial!!

2
1123Puntos

Podrías incluir que existen los operadores rest y spread para estas tareas también. Y aclarar que, según creo, stringify y parse no funcionan cuando dentro de tus objetos existen funciones definidas.

2
10235Puntos

Excelente post 😃

2
860Puntos

Con los ejemplos queda más que claro.

2
5440Puntos

¡Guau, excelente artículo! Ahora he aprendido un poco más de javascript. Ya sé que ahora hay que utilizar stringify and JSON.parse a la hora de utilizar objetos.
¡Gracias! 😄

2
2704Puntos

Muy buena, y simple como siempre.

2
23510Puntos

Usar JSON.parse y stringify? no me parece una muy buena practica que digamos, diríamos por acá en mi ciudad un machetazo es eso

1
9Puntos

Muchas gracias pro el post Juan

1
2451Puntos

Estos metodos solo copian los valores del objeto, pero lo que esta dentro de __proto__ se pierde, ¿Hay alguna forma de copiar todo el objeto, incluyendo lo que esta dentro de __proto__?