A pesquisa no "objeto clone javascript" traz alguns resultados realmente estranhos, alguns deles estão irremediavelmente desatualizados e outros são muito complexos, não é tão fácil quanto:
let clone = {...original};
Há algo de errado nisso?
javascript
ecmascript-6
javascript-objects
Dmitry Fadeev
fonte
fonte
original = { a: [1,2,3] }
dá a você um clone doclone.a
ser literaloriginal.a
. Modificação, quer através declone
ouoriginal
modifica a mesma coisa , de modo nenhum, isso é ruim =)Respostas:
Isso é bom para clonagem superficial . A propagação do objeto é uma parte padrão do ECMAScript 2018 .
Para clonagem profunda, você precisará de uma solução diferente .
const clone = {...original}
clone rasoconst newobj = {...original, prop: newOne}
para adicionar de forma imutável outro suporte ao original e armazenar como um novo objeto.fonte
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
não funcionará, porque se houverfunctions
ouinfinity
como valores, ele simplesmente atribuiránull
em seu lugar. Só funcionará se os valores forem simplesliterals
e nãofunctions
.EDIT: Quando esta resposta foi publicada, a
{...obj}
sintaxe não estava disponível na maioria dos navegadores. Atualmente, você deve estar bem em usá-lo (a menos que precise dar suporte ao IE 11).Use Object.assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
No entanto, isso não fará um clone profundo. Ainda não existe uma maneira nativa de clonagem profunda.
EDIT: Como o @Mike 'Pomax' Kamermans mencionado nos comentários, você pode clonar profundamente objetos simples (por exemplo, sem protótipos, funções ou referências circulares) usando
JSON.parse(JSON.stringify(input))
fonte
JSON.parse(JSON.stringify(input))
é um clone profundo adequado. No entanto, no momento em que protótipos, funções ou referências circulares estão em jogo, essa solução não funciona mais.Se os métodos utilizados não estiverem funcionando bem com objetos que envolvem tipos de dados como Data , tente este
Importar
_
Objeto de clone profundo
fonte
import _ from 'lodash';
é suficiente. Mas +1 na resposta "não reinvente a roda".se você não quiser usar o json.parse (json.stringify (object)), poderá criar cópias recursivas de valores-chave:
Mas a melhor maneira é criar uma classe que possa retornar um clone dele mesmo
fonte
Seguindo a resposta de @marcel, descobri que algumas funções ainda estavam ausentes no objeto clonado. por exemplo
onde no MyObject eu poderia clonar methodA, mas o methodB foi excluído. Isso ocorreu porque está faltando
o que significava que não apareceu em
Em vez disso, mudei para
que incluirá chaves não enumeráveis.
Também descobri que o protótipo ( proto ) não era clonado. Por isso acabei usando
PS: Frustrante não conseguir encontrar uma função incorporada para fazer isso.
fonte
Você pode fazer assim também,
fonte
Mas Object.assign () não cria um clone profundo
Para consertar isso, devemos usar o loop de clonagem que examina cada valor do usuário [chave] e, se for um objeto, replicar sua estrutura também. Isso é chamado de "clonagem profunda".
Existe um algoritmo padrão para clonagem profunda que lida com o caso acima e casos mais complexos, chamado algoritmo de clonagem estruturada . Para não reinventar a roda, podemos usar uma implementação funcional da biblioteca JavaScript lodash, o método é chamado _.cloneDeep (obj) .
fonte
Todos os métodos acima não tratam de clonagem profunda de objetos nos quais está aninhado em n níveis. Não verifiquei seu desempenho em relação aos outros, mas é curto e simples.
O primeiro exemplo abaixo mostra a clonagem de objetos usando
Object.assign
quais clones até o primeiro nível.Usando o objeto de clones profundos da abordagem abaixo
fonte