-1

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?

  • Shallow copy only. – VLAZ Jan 21 '21 at 09:41
  • If you do `key.newProp = 10`, it will be reflected in `obj` because they are both refereceing the same object. But, `key = { }` is just changing variable's value. [Is JavaScript a pass-by-reference or pass-by-value language?](https://stackoverflow.com/questions/518000) – adiga Jan 21 '21 at 09:50
  • But either way (shallow or deep), your `key = {msg: 'hello'}` assignment will have no effect whatsoever on `obj` or the objects in it. – T.J. Crowder Jan 21 '21 at 09:50
  • Just for what it's worth, the word is "destructuring" (extracting something from a structure), not "destructing" (destroying). – T.J. Crowder Jan 21 '21 at 10:04

2 Answers2

2
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.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    Your answer is quite a detail along with useful for me, any +1 –  Jan 21 '21 at 09:59
  • 1
    (FWIW, I go into destructuring in a fair bit of detail in Chapter 7 of my recent book, *JavaScript: The New Toys*. Links in my profile if you're interested.) – T.J. Crowder Jan 21 '21 at 10:07