Buscar en Google "objeto de clonación de JavaScript" trae algunos resultados realmente extraños, algunos de ellos están irremediablemente desactualizados y otros son demasiado complejos, ¿no es tan fácil como:
let clone = {...original};
¿Hay algo malo con esto?
javascript
ecmascript-6
javascript-objects
Dmitry Fadeev
fuente
fuente
original = { a: [1,2,3] }
te da un clon conclone.a
ser literalmenteoriginal.a
. Modificación a través declone
ooriginal
modifica la misma cosa , así que no, esto es malo =)Respuestas:
Esto es bueno para la clonación superficial . La propagación del objeto es una parte estándar de ECMAScript 2018 .
Para una clonación profunda, necesitará una solución diferente .
const clone = {...original}
clon superficialconst newobj = {...original, prop: newOne}
para agregar de manera inmutable otro accesorio al original y almacenarlo como un nuevo objeto.fuente
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
no funcionará, porque si existefunctions
oinfinity
como valores, simplemente se asignaránull
en su lugar. Solo funcionará si los valores son simplesliterals
y nofunctions
.EDITAR: cuando se publicó esta respuesta, la
{...obj}
sintaxis no estaba disponible en la mayoría de los navegadores. Hoy en día, deberías estar bien usándolo (a menos que necesites soportar IE 11).Use Object.assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Sin embargo, esto no hará un clon profundo. Todavía no existe una forma nativa de clonación profunda.
EDITAR: Como @Mike 'Pomax' Kamermans mencionó en los comentarios, puede clonar objetos simples (es decir, sin prototipos, funciones o referencias circulares) usando
JSON.parse(JSON.stringify(input))
fuente
JSON.parse(JSON.stringify(input))
es un clon profundo adecuado. Sin embargo, en el momento en que los prototipos, funciones o referencias circulares están en juego, esa solución ya no funciona.Si los métodos que usó no funcionan bien con objetos que involucran tipos de datos como Fecha , intente esto
Importar
_
Objeto clon profundo
fuente
import _ from 'lodash';
es suficiente. Pero +1 para la respuesta "no reinventar la rueda".si no desea utilizar json.parse (json.stringify (objeto)), puede crear copias recursivamente de valor clave:
Pero la mejor manera es crear una clase que pueda devolver un clon de sí mismo
fuente
Siguiendo con la respuesta de @marcel, encontré que todavía faltaban algunas funciones en el objeto clonado. p.ej
donde en MyObject pude clonar el método A pero se excluyó el método B. Esto ocurrió porque falta
lo que significaba que no apareció en
En cambio, cambié a
que incluirá claves no enumerables.
También descubrí que el prototipo ( proto ) no estaba clonado. Para eso terminé usando
PD: Frustrante que no pude encontrar una función integrada para hacer esto.
fuente
Puedes hacerlo así también,
fuente
Pero Object.assign () no crea un clon profundo
Para solucionarlo, deberíamos usar el ciclo de clonación que examina cada valor de usuario [clave] y, si es un objeto, replicar también su estructura. Eso se llama una "clonación profunda".
Hay un algoritmo estándar para la clonación profunda que maneja el caso anterior y casos más complejos, llamado algoritmo de clonación estructurada . Para no reinventar la rueda, podemos usar una implementación funcional desde la biblioteca de JavaScript, ya que el método se llama _.cloneDeep (obj) .
fuente
Todos los métodos anteriores no manejan la clonación profunda de objetos donde está anidada en n niveles. No verifiqué su rendimiento sobre otros, pero es breve y simple.
El primer ejemplo a continuación muestra la clonación de objetos usando
Object.assign
qué clones hasta el primer nivel.Usando el siguiente enfoque clones profundos objeto
fuente