Je veux savoir s'il y a une différence entre
Object.assign({}, obj)
et
JSON.parse(JSON.stringify(obj))
pour le clonage en profondeur d'un objet? Quelqu'un peut-il expliquer s'il a une idée?
La différence est que
Object.assign({}, obj)
crée un copie superficielle , pas deep , tandis que
JSON.parse(JSON.stringify(obj))
sérialise l'objet sous forme de chaîne JSON puis le désérialise, créant efficacement une copie complète.
Une copie superficielle est très bien, si toutes vos propriétés pointent vers des valeurs primitives, ou si vous n'avez pas l'intention de muter les objets référencés par la copie. Si vous le faites, les modifications seront visibles à la fois dans l'original et dans la copie superficielle, car elles font toutes deux référence au même objet:
> let a = { k: { h: 1 } };
> let b = Object.assign({}, a);
> b.k.h = 2;
> a
{ k: { h: 2 } }
> b
{ k: { h: 2 } }
Vous pouvez bien sûr muter la copie elle-même sans que cela n'ait d'effet sur l'original:
> b.j = 4
> b.k = { new: 'object' }
> a
{ k: { h: 2 } }
> b
{ k: { new: 'object' }, j: 4 }
L'astuce serialize-deserialize, d'autre part, crée une copie complète où tout est créé à partir de zéro:
> let c = JSON.parse(JSON.stringify(b));
> c
{ k: { h: 2 } }
> c.k.h = 3
> c
{ k: { h: 3 } }
> a
{ k: { h: 2 } }
> b
{ k: { h: 2 } }
Une autre façon d'inspecter les identités consiste à utiliser une stricte égalité:
> let a = { k: { h: 1 } };
> let b = Object.assign({}, a);
> a.k === b.k // both point to the same object
true
> let c = JSON.parse(JSON.stringify(b));
> c.k === b.k // different objects
false