'Is destructing assigning in JavaScript shallow or deep copy?
I'm confused by the destructing assigning in JavaScript about shallow and deep copy. For example,
const obj = {key:{}, value:{}}
let {key} = obj
key = {msg: 'hello'}
Is the value of key
in the sample above a shallow or deep copy of the key
in obj
? What is the value of key
should be?
Solution 1:[1]
let {key} = obj
… is the same as saying:
let key = obj.key
It is a shallow copy.
key = {msg: 'hello'}
… overwrites the reference to the object that also exists in obj.key
with a reference to a new object.
This renders the previous line pointless as nothing was done with the value before it was overwritten.
Solution 2:[2]
It's shallow, though there's some nuance.
This:
let {key} = obj;
has exactly the same result as this:
let key = obj.key;
E.g., all it does is copy the value of obj.key
into key
, making both of them point to the same object — a shallow copy, if the word "copy" really applies. (Normally I think of a "shallow copy" as copying multiple properties, not just one, like Object.assign
does.)
You can reach deeper into the object graph you're retrieving from by using nested destructuring:
const obj = {
a: {
b: {
c: {
d: "hi",
},
},
},
};
const {a: {b: {c}}} = obj;
console.log(c.d); // "hi"
but at the end of the day it's just like an assignment, so it's just grabbing the object reference (if the value is an object reference), not a copy of the object:
const obj = {
a: {
b: {
c: {
d: "hi",
},
},
},
};
const {a: {b: {c}}} = obj;
console.log(c.d); // "hi"
console.log(obj.a.b.c.d); // "hi"
c.d = c.d.toLocaleUpperCase();
console.log(c.d); // "HI"
console.log(obj.a.b.c.d); // "HI"
But, even if it were a deep copy, your code still wouldn't change anything in obj
, because you're changing the value of what's in key
(an object reference), not the state of the object that reference refers to. After let {key} = obj
, key
is completely disconnected from obj.key
other than that they both refer to the same object. If you change the value in key
, the variable, it has no effect on the object it refers to. If you're goign to do key = ...
, there's no point to let {key} = obj
at all, just use let key
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Quentin |
Solution 2 |