Détails
Quel est le moyen le plus efficace de cloner profondément un objet en JavaScript ?
Quel est le moyen le plus efficace de cloner un objet JavaScript ? J'ai vu l'utilisation de obj = eval(uneval(o));
, mais [ce n'est pas standard et n'est supporté que par Firefox][1].
J'ai fait des choses comme obj = JSON.parse(JSON.stringify(o));
mais je m'interroge sur l'efficacité.
J'ai aussi vu des fonctions de copie récursive avec divers défauts.
Je suis surpris qu'il n'existe pas de solution canonique.
[1] : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/uneval
5181
3
Clonage profond natif
C'est ce qu'on appelle le "clonage structuré", qui fonctionne expérimentalement dans Node 11 et les versions ultérieures, et qui, espérons-le, sera disponible dans les navigateurs. Voir cette réponse pour plus de détails.
Clonage rapide avec perte de données - JSON.parse/stringify
Si vous n'utilisez pas de
Date
s, de fonctions, deundefined
, deInfinity
, de RegExps, de Maps, de Sets, de Blobs, de FileLists, d'ImageDatas, de sparse Arrays, de Typed Arrays ou d'autres types complexes dans votre objet, une méthode très simple pour cloner profondément un objet est :JSON.parse(JSON.stringify(object))
.Voir la réponse de Corban pour des points de repère.
Clonage fiable à l'aide d'une bibliothèque
Puisque le clonage d'objets n'est pas trivial (types complexes, références circulaires, fonction etc.), la plupart des bibliothèques majeures fournissent une fonction pour cloner des objets. Ne réinventez pas la roue - si vous utilisez déjà une bibliothèque, vérifiez si elle possède une fonction de clonage d'objets. Par exemple,
cloneDeep
; peut être importé séparément via le module lodash.clonedeep et est probablement votre meilleur choix si vous n'utilisez pas déjà une bibliothèque qui fournit une fonction de clonage profondangular.copy
jQuery.extend(true, { }, oldObject)
;.clone()
ne clone que les éléments du DOM.ES6
Pour être complet, notez que ES6 offre deux mécanismes de copie superficielle :
Object.assign()
et l'opérateur spread.S'il n'y en avait pas un intégré, vous pourriez essayer :