faire une copie superficielle d’un tableau ou d’un objet signifie créer de nouvelles références aux valeurs primitives à l’intérieur de l’objet, en les copiant.
cela signifie que les modifications apportées au tableau d’origine n’affecteront pas le tableau copié, ce qui se produirait si seule la référence au tableau avait été copiée (comme cela se produirait avec l’opérateur d’affectation=
).
Une copie superficielle fait référence au fait qu’un seul niveau est copié, et cela fonctionnera bien pour un tableau ou un objet contenant uniquement des valeurs primitives.,
pour les objets et les tableaux contenant d’autres objets ou tableaux, la copie de ces objets nécessite une copie en profondeur. Sinon, les modifications apportées aux références imbriquées modifieront les données imbriquées dans l’objet ou le tableau d’origine.
dans cet article, je décris 4 méthodes pour faire une copie superficielle, puis 5 méthodes pour faire une copie profonde en JavaScript.,
copie à l’aide …
1. L’opérateur de propagation (…
) est un moyen pratique de faire une copie peu profonde d’un tableau ou d’un objet —lorsqu’il n’y a pas d’imbrication, cela fonctionne très bien.,
Comme indiqué ci-dessus, la propagation de l’opérateur est utile pour la création de nouvelles instances de tableaux qui ne se comportent pas de façon inattendue en raison d’anciennes références. L’opérateur spread est donc utile pour ajouter à un tableau dans L’état React.
copie à l’aide .slice ()
2.,Pour des tableaux plus précisément, en utilisant le haut-.slice()
méthode fonctionne de la même que la propagation de l’opérateur — la création d’une copie d’un niveau:
copie à l’aide .assign ()
3.,Le même type de copie serait créé à l’aide de Object.assign()
, qui peut être utilisé avec n’importe quel objet ou un tableau:
copie de tableaux à l’aide de Tableau.à partir de()
4.,Une autre méthode pour copier un tableau JavaScript utilise Array.from()
, qui fera également une copie peu profonde, comme indiqué dans cet exemple:
Une fonction personnalisée ou les bibliothèques mentionnées peuvent faire une copie profonde sans avoir à se soucier du type du contenu, bien que les références circulaires les déclenchent toutes.,
Next I discuss a blazing-fast library called rfdc
that can handle circular references while being as fast as a custom deep copy function.
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
rfdc
est assez simple, comme dans beaucoup d’autres bibliothèques:
Le rfdc
bibliothèque prend en charge tous les types et prend également en charge les références circulaires en option avec un drapeau qui diminue les performances d’environ 25%.
les références circulaires briseront les autres algorithmes de copie profonde discutés.,
Une telle bibliothèque serait utile si vous avez affaire à un objet volumineux et complexe tel qu’un objet chargé à partir de fichiers JSON de 3 Mo à 15 Mo.,e les copies superficielles sont les plus rapides, suivies des copies profondes utilisant une fonction personnalisée ou rfdc
:
« copie profonde par performance: classée du meilleur au pire
réaffectation «
=
” (tableaux de chaînes, tableaux de nombres uniquement)slice (tableaux de chaînes, tableaux de nombres uniquement)
concaténation (tableaux de chaînes, tableaux de nombres uniquement)
fonction personnalisée: For — Loop ou recursive copy
jquery
$.extend
JSON.parse
(tableaux de chaînes, nombre arrays, object arrays — only)underscore.,js
_.clone
(tableaux de chaînes, tableaux de nombres uniquement)Lo — Dash
_.cloneDeep
”-Tim Montague dans sa réponse StackOverflow
En utilisant JSON.parse
/JSON.stringify
crée des problèmes autour des types de données, donc rfdc
est recommandé — sauf si vous souhaitez écrire une fonction personnalisée.,
Conclusion
Il est en fait assez facile pour éviter de devoir copie en profondeur en JavaScript — si vous ne pouvez jamais imbriquer les objets et les tableaux à l’intérieur les uns des autres.,
parce que dans ce cas — où il n’y a pas d’imbrication et que les objets et les tableaux ne contiennent que des valeurs primitives — faire une copie peu profonde avec l’opérateur de propagation (…
),.slice()
et.assign()
fonctionnent tous très bien.
Mais, dans le monde réel, où les objets ont des tableaux à l’intérieur, ou vice versa, alors une copie profonde devra être utilisée. Je recommande rfdc
pour les clones profonds.,
(Note que certains peuvent également suggérer d’utiliser des JSON.stringify()
suivi de JSON.parse()
, mais ce n’est pas un moyen fiable de faire une copie en profondeur.)
maintenant, sortez et copiez en profondeur certains objets imbriqués!
lecture
- Alligator.,io a un excellent article sur le clonage profond en utilisant lodash:
- Samantha Ming explique les copies peu profondes et profondes sur dev.to:
- article de Peter Tasker sur dev.,pour générer de nombreux commentaires, y compris une explication de l’échec de
JSON.parse(JSON.stringify(obj))
:
- James Dorr couvre la nécessité de copier lors de l’ajout à un tableau pour React State (puisque React State est immuable) en JavaScript en anglais simple:
- Ramón Miklus utilise immutability-helper, une bibliothèque utilisée pour maintenir l’immutabilité des données, au lieu de lodash Codementor:
- En parlant d’immutabilité, Gabriel Lebec a un excellent guide en dev.,to: