Articles

como copiar profundamente objetos e Arrays em JavaScript

Posted by admin

fazer uma cópia rasa de um array ou objeto significa criar novas referências aos valores primitivos dentro do objeto, copiando-os.

isso significa que as mudanças no array original não afetarão o array copiado, que é o que aconteceria se apenas a referência ao array tivesse sido copiada (tal como ocorreria com o operador de atribuição =).

uma cópia rasa refere-se ao fato de que apenas um nível é copiado, e que vai funcionar bem para um array ou objeto contendo apenas valores primitivos.,

para objetos e matrizes contendo outros objetos ou matrizes, copiar esses objetos requer uma cópia profunda. Caso contrário, as alterações feitas às referências aninhadas irão alterar os dados aninhados no objeto ou array original.

neste artigo, eu descrevo 4 métodos de fazer uma cópia rasa e, em seguida, 5 métodos de fazer uma cópia profunda em JavaScript.,

Foto por Jakob Owens no Unsplash

cópia Superficial usando …

1. O operador de spread () é uma maneira conveniente de fazer uma cópia rasa de um array ou objeto —quando não há nidificação, ele funciona bem.,

conforme mostrado acima, o operador de spread é útil para criar novas instâncias de arrays que não se comportam inesperadamente devido a referências antigas. O operador de spread é, portanto, útil para adicionar a um array em estado de reação.

Foto por Donald Giannatti no Unsplash

cópia Superficial usando .fatia ()

2.,Para matrizes especificamente, usando o built-in .slice() método funciona da mesma forma que a propagação operador — a criação de uma cópia superficial de um nível:

Foto por Antonio Garcia-em Unsplash

cópia Superficial usando .atribuir ()

3.,O mesmo tipo de cópia superficial seria criado usando Object.assign(), que pode ser usada com qualquer objeto ou array:

Foto Paweł Czerwiński no Unsplash

cópia Superficial matrizes usando a Matriz.de ()

4.,Outro método para copiar um array JavaScript está usando Array.from(), que irá também fazer uma cópia superficial, como mostrado neste exemplo:

Se um objeto ou array contém outros objetos ou matrizes, rasa cópias irá funcionar inesperadamente, porque objetos aninhados na verdade, não são clonados.

para objetos profundamente aninhados, uma cópia profunda será necessária. Eu explico porquê abaixo.,

Foto brabus biturbo no Unsplash

atente para o aninhadas Gotcha!

por outro lado, quando objetos JavaScript incluindo arrays são profundamente aninhados, o operador de spread só copia o primeiro nível com uma nova referência, mas os valores mais profundos ainda estão ligados entre si.,

Para resolver este problema requer a criação de uma cópia de profundidade, em oposição a uma cópia superficial. Cópias profundas podem ser feitas usando lodash, rfdc, ou o método R. clone() da biblioteca de programação funcional Ramda. A seguir, exploro cópias profundas.

Fotos por Sérgio Martinho em Unsplash

o Que é uma cópia profunda?,

para objetos e matrizes contendo outros objetos ou matrizes, copiar esses objetos requer uma cópia profunda. Caso contrário, as alterações feitas às referências aninhadas irão alterar os dados aninhados no objeto ou array original.

isto é comparado a uma cópia rasa, que funciona bem para um objeto ou array contendo apenas valores primitivos, mas irá falhar para qualquer objeto ou array que tenha referências aninhadas a outros objetos ou arrays., diferença entre == e === pode ajudar a visualizar a diferença entre o raso e o profundo cópia, como o operador de igualdade estrita (===) mostra que o aninhadas referências são as mesmas:

Foto por mya que khine no Unsplash

cópia de Profundidade com lodash

1.,O lodash da Biblioteca é a forma mais comum de desenvolvedores JavaScript fazer uma cópia profunda. É surpreendentemente fácil de usar:

Lodash do nome vem da biblioteca que está sendo referenciado como um carácter de sublinhado (_), um “baixo traço” ou lodash para breve.

Foto: Annie Spratt na Unsplash

cópia de Profundidade com Ramda

2.,A biblioteca de programação funcional Ramda inclui o método R.clone(), que faz uma cópia profunda de um objeto ou array.

Note que R.clone() a partir de Ramda é equivalente a _.cloneDeep() para lodash, como Ramda não tem uma cópia superficial método auxiliar.,

Foto Roi Dimor no Unsplash

cópia de Profundidade com função personalizada

3. É muito fácil escrever uma função JavaScript recursiva que fará uma cópia profunda de objetos aninhados ou arrays. Aqui está um exemplo:

Note que eu também preciso verificar nulo desde o typeof null é “o objeto.,”

Foto: Scott Webb em Unsplash

cópia de Profundidade com JSON.parse / stringify

4. Se os seus dados se ajustarem às especificações (ver abaixo), então JSON.parse seguido por JSON.stringify copiará profundamente o seu objecto.,plex tipos de dentro de seu objeto, de uma forma muito simples de um forro de profunda clonar um objeto é: JSON.parse(JSON.stringify(object))” — Dan Dascalescu em sua StackOverflow resposta

Para demonstrar algumas razões pelas quais este método não é recomendado, aqui está um exemplo de como criar uma cópia de profundidade, usando o JSON.parse(JSON.stringify(object)):

Uma função personalizada ou bibliotecas mencionadas pode fazer uma cópia de profundidade sem precisar se preocupar com o tipo de conteúdo, apesar de circular referências viagem de todos eles para cima.,

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 Documentação

Usando a tag rfdc é bem simples, muito parecido com o de outras bibliotecas:

rfdc biblioteca de suporte a todos os tipos e também suporta referências circulares opcional com um sinalizador que diminui o desempenho em cerca de 25%.

referências circulares irão quebrar os outros algoritmos de cópia profunda discutidos.,

tal biblioteca seria útil se você estiver lidando com um objeto grande e complexo, como um carregado de arquivos JSON de 3MB-15MB em tamanho.,e rasa cópias é o mais rápido, seguido por um profundo cópias utilizando uma função personalizada ou rfdc:

“cópia de Profundidade por desempenho: Ranking da melhor para a pior

Redesignação “=” (matrizes de seqüência de caracteres, número de matrizes — apenas)

Fatia (matrizes de seqüência de caracteres, número de matrizes só)

Concatenação (matrizes de seqüência de caracteres, número de matrizes só)

função Personalizada: for-loop ou cópia recursiva

jQuery $.extend

JSON.parse (matrizes de seqüência de caracteres, número de matrizes, as matrizes de objeto somente)

Sublinhado.,js do _.clone (matrizes de seqüência de caracteres, número de matrizes — apenas)

Eis o Traço do _.cloneDeep” — Tim Montague em sua StackOverflow resposta

Usando a tag JSON.parse/JSON.stringify cria problemas em torno de tipos de dados, portanto, rfdc é recomendado, a menos que você queira escrever uma função personalizada.,

Foto por Keila Hotzel no Unsplash

Conclusão

é realmente muito fácil para evitar ter de cópia de profundidade em JavaScript — se que você pode nunca ninho objetos e arrays dentro de si.,

porque nesse caso — onde não há nidificação e os objetos e arrays apenas contêm valores primitivos-fazendo uma cópia rasa com o operador de propagação (), .slice(), e todo o trabalho grande.

mas, no mundo real, onde os objetos têm matrizes dentro deles, ou vice-versa, então uma cópia profunda terá de ser usada. Eu recomendo rfdc para clones profundos.,

(Note que alguns também podem sugerir o uso de JSON.stringify()seguido deJSON.parse(), mas isso não é uma maneira confiável de fazer uma cópia profunda.)

Agora saia e copie profundamente alguns objetos aninhados!

Foto por Kristina Evstifeeva no Unsplash

ler Mais

  • o Jacaré.,lo tem um grande artigo sobre clonagem profunda usando lodash:
  • Samantha Ming explica cópias rasas e profundas em dev.to:
  • artigo de Peter Tasker sobre dev.,para gerou muitos comentários, incluindo uma explicação de quando JSON.parse(JSON.stringify(obj)) falha:
  • James Dorr cobre a necessidade de copiar quando adicionando uma matriz para Reagir Estado (desde Reagir Estado é imutável) em JavaScript em inglês:
  • Ramón Miklus usa imutabilidade-ajudante, uma biblioteca usada para manter a imutabilidade de dados, em vez de lodash para cópia de profundidade no Codementor:
  • Falando de imutabilidade, Gabriel Lebec tem um ótimo guia no dev.,to:

Photo by 青 晨 on Unsplash

Leave A Comment