Martial
Martial

Reputation: 1562

Delete nested property of cloned object with Object.assign() affect original object

Is someone can explain me this behavior ?

const object1 = {
  a: {
    d : 1,
    e : 4
  },
  b: 2,
  c: 3
};

const object2 = Object.assign({}, object1);
console.log('object1 :', object1);
console.log('object2 :', object2);
delete object2.a;
console.log('object1 :', object1);
console.log('object2 :', object2);

If I delete a, only object2 is affected.

> "object1 :" Object { a: Object { d: 1, e: 4 }, b: 2, c: 3 }
> "object2 :" Object { a: Object { d: 1, e: 4 }, b: 2, c: 3 }
> "object1 :" Object { a: Object { d: 1, e: 4 }, b: 2, c: 3 }
> "object2 :" Object { b: 2, c: 3 }

And if I delete a nested property...

const object2 = Object.assign({}, object1);
console.log('object1 :', object1);
console.log('object2 :', object2);
delete object2.a.d;
console.log('object1 :', object1);
console.log('object2 :', object2);

Both object1 and object2 lose the property d.

> "object1 :" Object { a: Object { d: 1, e: 4 }, b: 2, c: 3 }
> "object2 :" Object { a: Object { d: 1, e: 4 }, b: 2, c: 3 }
> "object1 :" Object { a: Object { e: 4 }, b: 2, c: 3 }
> "object2 :" Object { a: Object { e: 4 }, b: 2, c: 3 }

Why ?

Upvotes: 2

Views: 538

Answers (3)

nisar
nisar

Reputation: 1065

Hi reffered from

You can use OBJECT COPY AS following

const object1 = {
  a: {
    d : 1,
    e : 4
  },
  b: 2,
  c: 3
};

const objecct2 = JSON.parse(JSON.stringify(object1));

Upvotes: 0

Logar
Logar

Reputation: 1248

When you are doing :

const object2 = Object.assign({}, object1);

You are assigning the properties of object1 to a new object, that will be stored in object2. In your case there is only one property of object1, that is a. But this is the same a that you put in object2 and that is in object1

Then, this line :

delete object2.a;

Just deletes the reference of the property a from object2. The property itself is not changed and will still exist if there are some other attached references to it.

In your second case, when you do :

delete object2.a.d;

you actually delete the reference of the property d from the object referenced by object2.a, which, remember, is the same as the object referenced by object1.a, so it indeed appears changed in both object1 and object2

Upvotes: 2

Marc
Marc

Reputation: 1467

On examples section in the documentation of assign (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign):

Warning for Deep Clone

For deep cloning, we need to use other alternatives because Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.

There are a specific example on how to deep clone an object:

JSON.parse(JSON.stringify(obj1))

And if you want more info about, there's an old thread on SO over this issue:

What is the most efficient way to deep clone an object in JavaScript?

Upvotes: 3

Related Questions