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.
📌Si te interesa profundizar en este tema, revisa nuestra Escuela de Javascript y descubre cursos completos y actualizados.
Los objetos merecen un trato especial y en este tutorial vamos a aprender a manejarlos como verdaderos profesionales del lenguaje.
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
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.
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.
¡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” ???????
¡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”!!
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! 💚
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.
Excelente no conocia esta forma
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
buena alternativa, aunque yo queria comentarla jajaja, pero no sabia que tenia los mismos problemas de Object.assign
Buen articulo esto les aclarara las dudas a muchos 😃
¿Cual es la diferencia entre el let, const y var?
solo se lo básico de javascript
Amigo, checa este link, allí podrás conocer las diferencias. Discuten sobre ese tema, y sin duda, se aclara muchas cosas. 😃
https://platzi.com/discusiones/1339-fundamentos-javascript/32001-cual-es-la-diferencia-entre-var-let-y-const/
¡Gracias! a penas me acabo de dar cuenta de que me respondiste. Ahora pienso que platzi debería mejorar su sistema de notificaciones
¡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! 😄
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.
Con los ejemplos queda más que claro.
No tenia idea de esta información, esta muy genial!!
Excelente post 😃
Muy buena, y simple como siempre.
Muy buena info
Tambien he visto que lo hacen con el spread operator
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!!!
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__
?Muchas gracias pro el post Juan