Parce que les objets en JavaScript sont des valeurs de référence, vous ne pouvez pas simplement copier en utilisant le=
. Mais pas de soucis, voici 3 façons de cloner un objet
# Les objets sont des types de référence
Votre première question pourrait être, pourquoi ne puis-je pas utiliser=
. Voyons ce qui se passe si nous faisons cela:
const obj = { one: 1, two: 2 };const obj2 = obj;console.log( obj, // {one: 1, two: 2}; obj2, // {one: 1, two: 2};);
Jusqu’à présent, les deux objets semblent produire la même chose. Donc pas de problème, à droite., Mais voyons ce qui se passe si nous modifier notre deuxième objet:
const obj2.three = 3;console.log(obj2);// {one: 1, two: 2, three: 3}; <-- ✅console.log(obj);// {one: 1, two: 2, three: 3}; <-- 😱
WTH?! J’ai changé obj2
mais pourquoi obj
aussi touchés. C’est parce que les objets sont des types de référence. Ainsi, lorsque vous utilisez =
, il a copié le pointeur sur l’espace mémoire qu’il occupe. Les types de référence ne contiennent pas de valeurs, ils sont un pointeur sur la valeur en mémoire.
Si vous voulez en savoir plus à ce sujet, consultez le cours Zhu Watch and Code de Gordon. Il est gratuit de s’inscrire et de regarder la vidéo « Comparaison avec des objets »., Il donne une explication super géniale à ce sujet.
# 1. Utiliser Spread
Utiliser spread clonera votre objet. Notez que ce sera une copie peu profonde. À partir de ce post, l’opérateur de propagation pour le clonage d’objets est au stade 4. Ce n’est donc pas encore officiellement dans les spécifications. Donc, si vous deviez l’utiliser, vous devrez le compiler avec Babel (ou quelque chose de similaire).
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = { ...food };console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# 2. À L’Aide De L’Objet.assign
Alternativement,Object.assign
est dans la version officielle et créera également une copie peu profonde de l’objet.,
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = Object.assign({}, food);console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
Notez le vide {}
le premier argument, cela vous permettra de ne pas la mutation de l’objet d’origine 👍
# 3. En utilisant JSON
Cette dernière façon vous donnera une copie profonde. Maintenant, je vais mentionner, c’est un moyen rapide et sale de cloner en profondeur un objet. Pour une solution plus robuste, je vous conseille d’utiliser quelque chose comme lodash
const food = { beef: '🥩', bacon: '🥓' };const cloneFood = JSON.parse(JSON.stringify(food));console.log(cloneFood);// { beef: '🥩', bacon: '🥓' }
# Lodash DeepClone vs JSON
Voici un commentaire de la communauté. Oui, c’était pour mon post précédent, Comment Cloner en profondeur un tableau ., Mais l’idée s’applique toujours aux objets.
Alfredo Salzillo : J’aimerais que vous notiez qu’il existe quelques différences entre deepClone et JSON.stringify/analyse.
- JSON.stringify / parse ne fonctionne qu’avec un nombre et une chaîne et un littéral d’objet sans propriétés de fonction ou de symbole.
- deepClone fonctionne avec tous les types, la fonction et le symbole sont copiés par référence.
Voici un exemple:
@OlegVaraksin : La méthode JSON a des problèmes avec les dépendances circulaires. De plus, l’ordre des propriétés dans l’objet cloné peut être différent.,
# Clone superficiel vs Clone profond
Lorsque j’ai utilisé spread...
pour copier un objet, je ne crée qu’une copie superficielle. Si le tableau est imbriqué ou multidimensionnel, cela ne fonctionnera pas. Voici notre exemple, nous allons utiliser:
const nestedObject = { flag: '🇨🇦', country: { city: 'vancouver', },};
# Copie
Laissez-clone de notre objet à l’aide de propagation:
const shallowClone = { ...nestedObject };// Changed our cloned objectshallowClone.flag = '🇹🇼';shallowClone.country.city = 'taipei';
nous avons Donc changé notre objet cloné par l’évolution de la ville. Nous allons voir le résultat.
console.log(shallowClone);// {country: '🇹🇼', {city: 'taipei'}}console.log(nestedObject);// {country: '🇨🇦', {city: 'taipei'}} <-- 😱
Une copie désigne le premier niveau est copié, des niveaux plus profonds sont référencés.,
# Deep Copy
Prenons le même exemple mais en appliquant une copie profonde en utilisant « JSON »
Comme vous pouvez le voir, la copie profonde est une copie vraie pour les objets imbriqués. Souvent, une copie peu profonde est assez bonne, vous n’avez pas vraiment besoin d’une copie profonde. C’est comme un pistolet à clous contre un marteau. La plupart du temps le marteau est parfaitement bien. L’utilisation d’un pistolet à clous pour certains petits arts et métiers est souvent une exagération, un marteau est très bien. Il s’agit d’utiliser le bon outil pour le bon travail
# Performance
Malheureusement, je ne peux pas écrire de test pour spread car il n’est pas encore officiellement dans la spécification., Néanmoins, je l’ai inclus dans le test afin que vous puissiez l’exécuter à l’avenir 😝. Mais le résultat montre Object.assign
c’est beaucoup plus rapide que JSON
.
Test de performance
# Entrée de la communauté
# Objet.assign vs Spread
@d9el: Il est important de noter cet objet.attribuer une fonction qui modifie et retourne l’objet cible. Dans de Samantha exemple d’utilisation de la suite,
const cloneFood = Object.assign({}, food);
{}
est l’objet est modifié., L’objet cible n’est référencé par aucune variable à ce stade, mais parce que Object.assign
renvoie l’objet cible, nous sommes en mesure de stocker l’objet assigné résultant dans la variable cloneFood
. On pourrait passer notre exemple et d’utiliser le code suivant:
const food = { beef: '🌽', bacon: '🥓' };Object.assign(food, { beef: '🥩' });console.log(food);// { beef: '🥩', bacon: '🥓' }
Évidemment, la valeur de beef
dans nos aliments objet est mal, afin que nous puissions affecter la valeur correcte de beef
à l’aide de Object.assign
., Nous n’utilisons pas du tout la valeur renvoyée de la fonction, mais nous modifions notre objet cible que nous avons référencé avec le const food
.
la Propagation sur l’autre main est un opérateur qui copie les propriétés d’un objet dans un nouvel objet., Si nous voulions répliquer l’exemple ci-dessus en utilisant spread pour modifier notre variable food...
const food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};// TypeError: invalid assignment to const `food'
...
nous obtenons une erreur, car nous utilisons spread lors de la création de nouveaux objets, et attribuons donc un nouvel objet entier à food
qui a été déclaré avec const
, ce qui est illégal., Donc on peut soit choisir de déclarer une nouvelle variable pour contenir notre objet, comme le suivant:
const food = { beef: '🌽', bacon: '🥓' };const newFood = { ...food, beef: '🥩',};console.log(newFood);// { beef: '🥩', bacon: '🥓' }
ou nous pourrions déclarer food
par let
ou var
, ce qui nous permettrait d’attribuer un tout nouvel objet:
let food = { beef: '🌽', bacon: '🥓' };food = { ...food, beef: '🥩',};console.log(food);// { beef: '🥩', bacon: '🥓' }
Merci: @d9el
# Profonde Clone à l’aide de Bibliothèques Externes
# Plus de Moyens à l’aide de JavaScript
- @hariharan_d3v :
Object.fromEntries(Object.entries(food))
clones de l’objet.
Laisser un commentaire