La recherche sur Google de "javascript clone object" apporte des résultats vraiment étranges, certains d'entre eux sont désespérément obsolètes et certains sont tout simplement trop complexes, n'est-ce pas aussi simple que:
let clone = {...original};
Y a-t-il quelque chose de mal à cela?
javascript
ecmascript-6
javascript-objects
Dmitry Fadeev
la source
la source
original = { a: [1,2,3] }
vous donne un clone avecclone.a
être littéralementoriginal.a
. Modification via l'unclone
ou l' autre ouoriginal
modifie la même chose , donc non, c'est mauvais =)Réponses:
C'est bon pour le clonage superficiel . La diffusion d'objets fait partie intégrante d'ECMAScript 2018 .
Pour le clonage profond, vous aurez besoin d'une solution différente .
const clone = {...original}
cloner peu profondconst newobj = {...original, prop: newOne}
pour ajouter immuablement un autre accessoire à l'original et le stocker en tant que nouvel objet.la source
JSON.parse(JSON.stringify(input))
JSON.parse(JSON.stringify(input))
ne fonctionnera pas, car s'il existefunctions
ou eninfinity
tant que valeurs, il les attribuera simplementnull
à leur place. Cela ne fonctionnera que si les valeurs sont simplesliterals
et nonfunctions
.EDIT: Lorsque cette réponse a été publiée,
{...obj}
syntaxe n'était pas disponible dans la plupart des navigateurs. De nos jours, vous devriez bien l'utiliser (à moins que vous n'ayez besoin de prendre en charge IE 11).Utilisez Object.assign.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Cependant, cela ne fera pas un clone profond. Il n'existe pas encore de méthode native de clonage profond.
EDIT: Comme @Mike 'Pomax' Kamermans l'a mentionné dans les commentaires, vous pouvez cloner en profondeur des objets simples (c'est-à-dire pas de prototypes, de fonctions ou de références circulaires) en utilisant
JSON.parse(JSON.stringify(input))
la source
JSON.parse(JSON.stringify(input))
s'agit d'un clone profond approprié. Cependant, au moment où des prototypes, des fonctions ou des références circulaires sont en jeu, cette solution ne fonctionne plus.Si les méthodes que vous avez utilisées ne fonctionnent pas correctement avec des objets impliquant des types de données tels que Date , essayez ceci
Importer
_
Objet clone profond
la source
import _ from 'lodash';
suffisant. Mais +1 pour la réponse "ne réinventez pas la roue".si vous ne souhaitez pas utiliser json.parse (json.stringify (object)), vous pouvez créer des copies clé-valeur de manière récursive:
Mais le meilleur moyen est de créer une classe qui peut renvoyer un clone d'elle-même
la source
Suite à la réponse de @marcel, j'ai trouvé que certaines fonctions manquaient toujours sur l'objet cloné. par exemple
où sur MyObject je pourrais cloner methodA mais methodB a été exclu. Cela s'est produit parce qu'il manque
ce qui signifiait qu'il n'apparaissait pas dans
Au lieu de cela, je suis passé à
qui comprendra des clés non énumérables.
J'ai également constaté que le prototype ( proto ) n'était pas cloné. Pour cela, j'ai fini par utiliser
PS: Frustrant que je n'ai pas pu trouver une fonction intégrée pour faire cela.
la source
Vous pouvez aussi le faire comme ça,
la source
Mais Object.assign () ne crée pas de clone profond
Pour résoudre ce problème, nous devrions utiliser la boucle de clonage qui examine chaque valeur de l'utilisateur [clé] et, s'il s'agit d'un objet, répliquer également sa structure. Cela s'appelle un «clonage en profondeur».
Il existe un algorithme standard pour le clonage profond qui gère le cas ci-dessus et les cas plus complexes, appelé algorithme de clonage structuré . Afin de ne pas réinventer la roue, nous pouvons utiliser une implémentation fonctionnelle de celle-ci à partir de la bibliothèque JavaScript lodash, la méthode s'appelle _.cloneDeep (obj) .
la source
Toutes les méthodes ci-dessus ne gèrent pas le clonage en profondeur des objets où il est imbriqué à n niveaux. Je n'ai pas vérifié ses performances par rapport aux autres mais c'est court et simple.
Le premier exemple ci-dessous montre le clonage d'objets en utilisant
Object.assign
quels clones jusqu'au premier niveau.Utilisation de l'objet de clones profonds d'approche ci-dessous
la source