Con JSON.stringify podemos convertir un objeto en un string y lo inverso con JSON.parse. Podríamos usar ambos métodos para lograr copiar un objeto en otro.
const obj1 ={a:'a',b:'b',c:{d:'d',e:'e',}}// Lo convertimos en String y el resultado lo asignamos en un variable:const stringifiedComplexObj =JSON.stringify(obj1);// Lo convertimos a objeto y lo asignamos al nuevo objeto:const obj2 =JSON.parse(stringifiedComplexObj);console.log(obj1);console.log(obj2);// Si hacemos modificaciones en un de los objetos...obj2.c.d="nested object";obj2.c.e="nested object";// El objeto original no se vería afectadoconsole.log(obj1);console.log(obj2);
De esta forma, aunque el objeto original tenga objetos anidados, es posible crear un nuevo objeto con las mismas propiedades del original sin que este se vea afectado ante modificaciones en los objetos copias.
Problemas para copiar un objeto con métodos
Con lo anterior pareciera que finalmente habíamos logrado dar solución a los convenientes que nos daba copiar objetos en otros. Sin embargo, tanto JSON.parse como JSON.stringify no saben trabajar con métodos, lo cual sería un nuevo inconveniente:
Para ello necesitamos utilizar Deep Copy para poder obtener una correcta copia de objetos. Antes de entrar en este concepto, debemos conocer qué es recursividad. ¡Vamos a ello! 🤔👩💻
Qué más necesitas saber acerca de JSON.stringify()
El método JSON.stringify() convierte un objeto o valor de JavaScript en una cadena JSON, reemplazando opcionalmente valores si se especifica una función de reemplazo u opcionalmente incluyendo solo las propiedades especificadas si se especifica una matriz de reemplazo.
Descripción
Los objetos Boolean, Number y String se convierten a sus valores primitivos, de acuerdo con la conversión semántica tradicional.
Si durante la conversión se encuentra un undefined, una Function, o un Symbol se omite (cuando se encuentra en un objeto) o se censura a null (cuando se encuentra en un array). JSON.stringify() puede devolver undefined cuando se pasan valores “puros” como JSON.stringify(function(){}) o JSON.stringify(undefined).
Todas las propiedades que utilicen Symbol en los nombres de la clave se ignoran por completo, incluso si utilizan una función replacer.
Las instancias de Date implementan la función toJSON() devolviendo una cadena de texto (igual que date.toISOString()). Por lo que son tratadas como strings.
Los números Infinity y NaN, así como el valor null, se consideran null. El resto de instancias de Object (incluyendo Map, Set, WeakMap, y WeakSet) solo tendrán serializadas sus propiedades enumerables.
JSON.stringify () convierte un valor en notación JSON que lo representa.
Qué más necesitas saber acerca de JSON.parse()
El método JSON.parse() analiza una cadena de texto (string) como JSON, transformando opcionalmente el valor producido por el análisis.
¿Por qué JSON.parse(JSON.stringify()) es una mala práctica para clonar un objeto en JavaScript?
Puedes perder tipos de datos.
JavaScript no te avisara cuando pierdas algún tipo de dato al usar JSON.stringify(), asi que GG mi rey
Convierte tipos de datos no soportados en soportados, como infinity y NaN en null
Los tipos de datos Date serán parseados como strings, no como Date
No es tan rápido y eficiente.
Contribución creada por: Martín Álvarez (Platzi Contributor) con el aporte de Carlos Mazzaroli.
Con JSON.stringify podemos convertir un objeto en un string y lo inverso con JSON.parse. Podríamos usar ambos métodos para lograr copiar un objeto en otro.
const obj1 = {
a: 'a',
b: 'b',
c: {
d: 'd',
e: 'e',
}
}
// Lo convertimos en String y el resultado lo asignamos en un variable:
const stringifiedComplexObj = JSON.stringify(obj1);
// Lo convertimos a objeto y lo asignamos al nuevo objeto:
const obj2 = JSON.parse(stringifiedComplexObj);
console.log(obj1);
console.log(obj2);
// Si hacemos modificaciones en un de los objetos...
obj2.c.d = "nested object";
obj2.c.e = "nested object";
// El objeto original no se vería afectado
console.log(obj1);
console.log(obj2);
De esta forma, aunque el objeto original tenga objetos anidados, es posible crear un nuevo objeto con las mismas propiedades del original sin que este se vea afectado ante modificaciones en los objetos copias.
Problemas para copiar un objeto con métodos
Con lo anterior pareciera que finalmente habíamos logrado dar solución a los convenientes que nos daba copiar objetos en otros. Sin embargo, tanto JSON.parse como JSON.stringify no saben trabajar con métodos, lo cual sería un nuevo inconveniente:
Para ello necesitamos utilizar Deep Copy para poder obtener una correcta copia de objetos. Antes de entrar en este concepto, debemos conocer qué es recursividad. ¡Vamos a ello! 🤔👩💻
Qué más necesitas saber acerca de JSON.stringify()
El método JSON.stringify() convierte un objeto o valor de JavaScript en una cadena JSON, reemplazando opcionalmente valores si se especifica una función de reemplazo u opcionalmente incluyendo solo las propiedades especificadas si se especifica una matriz de reemplazo.
Descripción
Los objetos Boolean, Number y String se convierten a sus valores primitivos, de acuerdo con la conversión semántica tradicional.
Si durante la conversión se encuentra un undefined, una Function, o un Symbol se omite (cuando se encuentra en un objeto) o se censura a null (cuando se encuentra en un array). JSON.stringify() puede devolver undefined cuando se pasan valores “puros” como JSON.stringify(function(){}) o JSON.stringify(undefined).
Todas las propiedades que utilicen Symbol en los nombres de la clave se ignoran por completo, incluso si utilizan una función replacer.
Las instancias de Date implementan la función toJSON() devolviendo una cadena de texto (igual que date.toISOString()). Por lo que son tratadas como strings.
Los números Infinity y NaN, así como el valor null, se consideran null. El resto de instancias de Object (incluyendo Map, Set, WeakMap, y WeakSet) solo tendrán serializadas sus propiedades enumerables.
JSON.stringify () convierte un valor en notación JSON que lo representa.
Qué más necesitas saber acerca de JSON.parse()
El método JSON.parse() analiza una cadena de texto (string) como JSON, transformando opcionalmente el valor producido por el análisis.
¿Por qué JSON.parse(JSON.stringify()) es una mala práctica para clonar un objeto en JavaScript?
Puedes perder tipos de datos.
JavaScript no te avisara cuando pierdas algún tipo de dato al usar JSON.stringify(), asi que GG mi rey
Convierte tipos de datos no soportados en soportados, como infinity y NaN en null
Los tipos de datos Date serán parseados como strings, no como Date
No es tan rápido y eficiente.
Contribución creada por: Martín Álvarez (Platzi Contributor) con el aporte de Carlos Mazzaroli.
El método JSON.stringify() convierte un objeto o valor de JavaScript en una cadena JSON, reemplazando opcionalmente valores si se especifica una función de reemplazo u opcionalmente incluyendo solo las propiedades especificadas si se especifica una matriz de reemplazo.
Descripción
Los objetos Boolean, Number, and String se convierten a sus valores primitivos, de acuerdo con la conversión semántica tradicional.
Si durante la conversión se encuentra un undefined, una Function, o un Symbol se omite (cuando se encuentra en un objeto) o se censura a null (cuando se encuentra en un array). JSON.stringify() puede devolver undefined cuando se pasan valores "puros" como JSON.stringify(function(){}) o JSON.stringify(undefined).
Todas las propiedades que utilicen Symbol en los nombres de la clave se ignoran por completo, incluso si utilizan una función replacer.
Las instancias de Date implementan la función toJSON() devolviendo una cadena de texto (igual que date.toISOString()). Por lo que son tratadas como strings.
Los números Infinity y NaN, así como el valor null, se consideran null.
El resto de instancias de Object (incluyendo Map, Set, WeakMap, y WeakSet) sólo tendrán serializadas sus propiedades enumerables.
JSON.stringify () convierte un valor en notación JSON que lo representa:
El método JSON.parse() analiza una cadena de texto (string) como JSON, transformando opcionalmente el valor producido por el análisis.
Why JSON.parse(JSON.stringify()) is a bad practice to clone an object in JavaScript
Puedes perder tipos de datos.
JavaScript no te avisara cuando pierdas algún tipo de dato al usar JSON.stringify(), asi que GG mi rey
Convierte tipos de datos no soportados en soportados, como infinity y NaN en null
Los tipos de datos Date serán parseados como strings, no como Date
Creo que JSON.stringify seria util cuando queremos validar si dos objetos son iguales, ya que siguiendo con el ejemplo si uno compara obj1 === obj2 da false.
obj1 == obj2
false
se pueden comparar como strings usando stringfy y asi retorna true.
JSON es un formato de texto sencillo para el intercambio de datos. Se trata de un subconjunto de la notación literal de objetos de JavaScript, aunque, debido a su amplia adopción como alternativa a XML, se considera un formato independiente del lenguaje.
Recursos
JSON.stringify() - JavaScript | MDN
JSON.parse() - JavaScript | MDN
Why JSON.parse(JSON.stringify()) is a bad practice to clone an object in JavaScript
Apuntes
JSON.stringify permite volver un objeto en una cadena de texto con formato JSON.
JSON.parse hace que una cadena de texto en formato JSON se vuelva un objeto JavaScript.
Si utilizamos ambos métodos podemos clonar un objeto JavaScript.
const obj2 = JSON.parse(JSON.stringify(obj1))
Lastimosamente, si tenemos una función JavaScript dentro de nuestro objeto, estas no se copiaran porque en formato JSON solo nos ayuda a guardar anotaciones no procedimientos.
Pero los objetos internos ya no estaran conectados a su referencia inicial, como cuando usabamos:
Object.assign
Object.create
📌 **RESUMEN:** Podemos usar el truco de implementar `JSON.stringify` y `JSON.parse` para clonar un objeto, pero en el procedimiento se pueden perder datos como funciones.
Con JSON.stringify podemos convertir un objeto en un string, pero no es lo mismo. y con JSON.parse podemos convertir un string en un objeto. ¿Confuso no?
nota: Ambos no saben trabajar con funciones
Estos dos métodos nos permiten crear una copia más profunda del objeto, sin tener el problema de las referencias de los objetos. Ya que JSON.stringify convierte el objeto en una cadena de texto, por lo cual no guarda la referencia al objeto.
Y parece que JSON.parse y JSON.stringify llegaron a resolvernos la vida 🥳, sin embargo no todo es bueno 😭. Si nosotros queremos hacer la copia de funciones, estos métodos no nos ayudarán
Compañeros, quería compartirles otra manera de copiar objetos de manera efectiva, y esta es utilizando el Spread Operator, el cual por definición nos permite expandir o distribuir los elementos de un array u objeto en aquellas partes del código que así lo requieran, aunque este no es el único uso que tiene, también lo podemos utilizar en una función cunado no sabemos exactamente cuantos parámetros va a recibir dicha función. Les recomiendo que investiguen mas acerca del Spread Operator, ps es bastante útil. Les dejo un link de un canal de Youtube que lo explica bastante bien : https://www.youtube.com/watch?v=_5V6siSlP2k.
También les dejo un pequeño código de ejemplo para copiar objetos
// Como es bien sabido al guardar un objeto en una variable, lo que en realidad sucede internamente en Java Script es que no almacenamos el objetos en dicha variable, si no que estamos alcenando un apuntador con la referencia en memoria de dicho objeto, cosa que nos acarrea algunos problemas, sobre todo a la hora de intentar copiar dicho objeto en otra variable, dicho problema podemos solucionarlo con el Spread Operator
const carro1 = {
marca: "Audi",
modelo: "Q5",
año: 2020,
color: "Gris plata"
}
// Vamos a realizar la copia del objeto en otro usando el spread operator
const carro2 = { ...carro1}
// Vamos a modificar algunos valores de ambos objetos a modo de ejemplo
carro1.marca = "Mercedez Benz";
carro2.año = 1997;
// Ahora vamos a mostrarlos en consola para que vean que funciona
console.log(`Carro 1: ${Object.entries(carro1)}`);
console.log(`Carro 2: ${Object.entries(carro2)}`);