使用Object.assign()删除克隆对象的嵌套属性会影响原始对象

时间:2018-03-19 09:06:48

标签: javascript ecmascript-6

有人能解释我这种行为吗?

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);

如果我删除a,则只有object2受到影响。

> "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 }

如果我删除嵌套属性......

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);

object1object2都失去了属性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 }

为什么?

3 个答案:

答案 0 :(得分:2)

当你这样做时:

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

您正在将object1的属性分配给新对象,该对象将存储在object2中。在您的情况下,object1只有一个属性,即a但是,这与您在object2中放置的a相同,而在object1中

然后,这一行:

delete object2.a;

只需从a删除属性object2的引用。该属性本身不会更改,如果有其他附加引用,它仍然存在。

在你的第二个案例中,当你这样做时:

delete object2.a.d;

您实际上从d引用的对象中删除了属性object2.a的引用,请记住,该引用与object1.a引用的对象相同,因此它确实显示已更改在object1object2

答案 1 :(得分:2)

在assign(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)文档中的示例部分:

  

深度克隆警告

     

对于深度克隆,我们需要使用其他替代方法,因为   Object.assign()复制属性值。如果源值是a   引用一个对象,它只复制该引用值。

有一个关于如何深度克隆对象的具体示例:

JSON.parse(JSON.stringify(obj1))

如果你想了解更多信息,那么在这个问题上SO上有一个旧线程:

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

答案 2 :(得分:0)

reffered from

您可以使用OBJECT COPY AS

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

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