Articles

cómo copiar profundamente objetos y matrices en JavaScript

Posted by admin

hacer una copia superficial de una matriz u objeto significa crear nuevas referencias a los valores primitivos dentro del objeto, copiándolos.

eso significa que los cambios en la matriz original no afectarán a la matriz copiada, que es lo que sucedería si solo se hubiera copiado la referencia a la matriz (como ocurriría con el operador de asignación =).

una copia superficial se refiere al hecho de que solo se copia un nivel, y que funcionará bien para una matriz u objeto que contenga solo valores primitivos.,

para los objetos y matrices que contienen otros objetos o matrices, copiar estos objetos requiere una copia profunda. De lo contrario, los cambios realizados en las referencias anidadas cambiarán los datos anidados en el objeto o matriz original.

en este artículo, describo 4 métodos para hacer una copia superficial y luego 5 métodos para hacer una copia profunda en JavaScript.,

Foto por Jakob Owens en Unsplash

copia Superficial utilizando …

1. El operador spread () es una forma conveniente de hacer una copia superficial de un array u objeto —cuando no hay anidamiento, funciona muy bien.,

como se muestra arriba, el operador spread es útil para crear nuevas instancias de matrices que no se comportan inesperadamente debido a referencias antiguas. Por lo tanto, el operador spread es útil para agregar a una matriz en estado React.

Foto por Donald Giannatti en Unsplash

copia Superficial de usar .slice ()

2.,Para las matrices específicamente, el uso de la incorporada en el .slice() método funciona de la misma como la propagación del operador — la creación de una copia superficial de un nivel:

Foto de Antonio García en la Unsplash

copia Superficial de usar .assign ()

3.,El mismo tipo de copia superficial podría ser creados usando Object.assign(), que puede ser utilizado con cualquier objeto o array:

Foto por Paweł Czerwiński en Unsplash

copia Superficial utilizando matrices Matriz.desde ()

4.,Otro método para copiar una matriz JavaScript es usar Array.from(), que también hará una copia superficial, como se muestra en este ejemplo:

Si un objeto o matriz contiene matrices, copias superficiales funcionarán inesperadamente, porque los objetos anidados no son en realidad clonados.

para objetos anidados profundamente, se necesitará una copia profunda. Explico por qué a continuación.,

Foto por brabus biturbo en Unsplash

Reloj hacia fuera para la anidadas Gotcha!

por otro lado, cuando los objetos JavaScript que incluyen matrices están profundamente anidados, el operador spread solo copia el primer nivel con una nueva referencia, pero los valores más profundos todavía están vinculados entre sí.,

Para resolver este problema requiere la creación de una copia en profundidad, en contraposición a una copia superficial. Se pueden hacer copias profundas usando lodash, rfdc, o el método R. clone() de la biblioteca de programación funcional Ramda. Exploraré copias profundas a continuación.

Foto por Landon Martin en Unsplash

¿Qué es una copia profunda?,

para los objetos y matrices que contienen otros objetos o matrices, copiar estos objetos requiere una copia profunda. De lo contrario, los cambios realizados en las referencias anidadas cambiarán los datos anidados en el objeto o matriz original.

esto se compara con una copia superficial, que funciona bien para un objeto o matriz que contiene solo valores primitivos, pero fallará para cualquier objeto o matriz que tenga referencias anidadas a otros objetos o matrices., la diferencia entre == y === puede ayudar a ver visualmente la diferencia entre superficial y profunda de copia, como el operador de igualdad estricta (===), muestra que las referencias anidadas son los mismos:

Foto mya thet khine en Unsplash

copia Profunda con lodash

1.,La biblioteca lodash es la forma más común en que los desarrolladores de JavaScript hacen una copia profunda. Es sorprendentemente fácil de usar:

Lodash que proviene el nombre de la biblioteca que se hace referencia como un carácter de subrayado (_), un «guión bajo» o lodash para el corto.

Foto de Annie Spratt en Unsplash

copia Profunda con Ramda

2.,La biblioteca de programación funcional Ramda incluye el método R.clone(), que hace una copia profunda de un objeto o matriz.

tenga en cuenta que R.clone() desde Ramda es equivalente a _.cloneDeep() para lodash, como Ramda no tiene una copia superficial método auxiliar.,

Foto por Roi Dimor en Unsplash

copia Profunda con la función personalizada

3. Es bastante fácil escribir una función JavaScript recursiva que hará una copia profunda de objetos anidados o matrices. He aquí un ejemplo:

tenga en cuenta que también tengo que comprobar el valor null ya que el typeof null es «objeto.,»

Foto por Scott Webb en Unsplash

copia Profunda con JSON.analizar / stringify

4. Si sus datos se ajustan a las especificaciones (consulte a continuación), JSON.parse seguido de JSON.stringify copiará profundamente su objeto.,tipos plex dentro de su objeto, un liner muy simple para clonar profundamente un objeto es: JSON.parse(JSON.stringify(object))» — Dan Dascalescu en su respuesta StackOverflow

para demostrar algunas razones por las que este método no se recomienda generalmente, aquí hay un ejemplo de creación de una copia profunda usando JSON.parse(JSON.stringify(object)):

una función personalizada o las bibliotecas mencionadas pueden hacer una copia profunda sin necesidad de preocuparse por el tipo de contenido, aunque las referencias circulares los dispararán a todos.,

Next I discuss a blazing-fast library called rfdc that can handle circular references while being as fast as a custom deep copy function.

Photo by Scott Webb on Unsplash

Really fast deep copy? Think rfdc

5.,622333″>

«rdfc clones all JSON types: •Object Array Number String null

With additional support for: •Date (copied) •undefined (copied) •Function (referenced) •AsyncFunction (referenced) •GeneratorFunction (referenced) •arguments (copied to a normal object)

All other types have output values that match the output of JSON.parse(JSON.stringify(o)).,»—rfdc Documentation

Usando rfdc es bastante sencillo, al igual que las otras bibliotecas:

la biblioteca rfdc admite todos los tipos y también admite referencias circulares con un indicador opcional que disminuye el rendimiento en aproximadamente un 25%.

Las referencias circulares romperán los otros algoritmos de copia profunda discutidos.,

una biblioteca de este tipo sería útil si se trata de un objeto grande y complejo, como uno cargado desde archivos JSON de 3MB a 15MB de tamaño.,e Las copias superficiales son las más rápidas, seguidas por las copias profundas usando una función personalizada o rfdc:

«copia profunda por rendimiento: clasificada de mejor a peor

reasignación «=» (matrices de cadenas, matrices de números — solo)

slice (string arrays, number arrays — only)

concatenación (string arrays, number arrays — only)

función personalizada: for-loop o copia recursiva

jQuery $.extend

JSON.parse (string arrays, number arrays, object arrays — only)

underscore.,js _.clone (string arrays, number arrays — only)

Lo-Dash _.cloneDeep» — Tim Montague en su respuesta StackOverflow

Usando JSON.parse/JSON.stringify crea problemas en torno a los tipos de datos, por lo que se recomienda rfdc, a menos que desee escribir una función personalizada.,

Foto por Keila Hötzel en Unsplash

Conclusión

en realidad, es bastante fácil de evitar la necesidad de copia profunda en JavaScript — si sólo se puede nunca nido de objetos y arrays dentro de la otra.,

porque en ese caso — donde no hay anidamiento y los objetos y matrices solo contienen valores primitivos — hacer una copia superficial con el operador spread (), .slice(), y .assign() todo funciona muy bien.

pero, en el mundo real, donde los objetos tienen matrices dentro de ellos, o viceversa, entonces se necesitará usar una copia profunda. Recomiendo rfdc para Clones profundos.,

(tenga en cuenta que algunos también pueden sugerir el uso de JSON.stringify() seguido de JSON.parse(), pero esa no es una forma confiable de hacer una copia profunda.)

Ahora sal y copia en profundidad algunos objetos anidados!

Foto de Kristina Evstifeeva en Unsplash

leer Más

  • Cocodrilo.,io tiene un gran artículo sobre clonación profunda usando lodash:
  • Samantha Ming explica las copias superficiales y profundas en dev.to:
  • El artículo de Peter Tasker sobre dev.,para generar muchos comentarios, incluyendo una explicación de cuando JSON.parse(JSON.stringify(obj)) falla:
  • James Dorr cubre la necesidad de copiar cuando se agrega a un array a React State (ya que React State es inmutable) en JavaScript en Inglés sencillo:
  • Ramón Miklus usa immutability-helper, una biblioteca utilizada para mantener la inmutabilidad de los datos, en lugar de lodash a deep copy en Codementor:
  • hablando de inmutabilidad, Gabriel Lebec tiene una gran guía en dev.,to:

Photo by 青 晨 on Unsplash

Leave A Comment