2015-12-29 80 views
15

我对面的JS:是否Object.assign()创建深拷贝和浅拷贝

var copy = Object.assign({}, originalObject); 

这个概念它创建原始对象的副本进入“copy”对象来了。但是,我的问题是,这种克隆对象的方式是创建一个深层副本还是一个浅层副本?

PS:令人困惑的是,如果它创建了一个深层副本,那么它将是克隆对象的最简单方法。

+0

文档是不言自明的我想道:“Object.assign()方法被用于从一个或多个源对象的所有**枚举自己**属性的值复制到目标对象”如果 – Sebas

回答

18

如果要复制的对象具有enumerable属性设置为false的属性,那么即使浅拷贝也是不安全的。

MDN:

的Object.assign()方法仅复制枚举和自己的属性 从源对象到目标对象

借此示例

var o = {}; 

Object.defineProperty(o,'x',{enumerable: false,value : 15}); 

var ob={}; 
Object.assign(ob,o); 

console.log(o.x); // 15 
console.log(ob.x); // undefined 
11

通过使用Object.assign(),你实际上在做浅拷贝你的对象。每当我们进行一项操作时,如将一个对象分配给另一个对象,我们实际上执行一个浅拷贝,即如果OBJ1是一个对象,则通过另一个OBJ2对象修改它也会反映OBJ1中的变化。

+15

它只是做一个浅拷贝,Redux如何工作?我认为它的重点在于对数据进行深度复制,以便在数据在商店外进行更改时,也不会改变商店内的数据。如果它是浅拷贝,那么数据将被链接,这导致即使没有派发,数据也会改变存储内容的问题,是否正确? – stackjlei

+0

我在Redux中遇到了同样的问题,最后我去了JSON.parse(JSON.stringify())。如果对象被另一个包所变异并产生递归问题,这也会产生问题。我正在寻找更好的选择。这种方法仍然是我正在使用的方法。 – Stu

3

它创建了一个浅拷贝,根据this paragraph from MDN

对于深克隆,我们需要使用其他的替代品,因为 Object.assign()副本的属性值。如果源值是对对象的 引用,则它只复制该引用值。

出于redux的目的,Object.assign()就足够了,因为redux应用的状态只包含不可变的值(JSON)。

+4

应用程序的redux状态不能包含引用其他对象的对象..? –

0

对于小Data structures我看到JSON.stringify()JSON.parse()工作很好。

// store as JSON 
var copyOfWindowLocation = JSON.stringify(window.location) 
console.log("JSON structure - copy:", copyOfWindowLocation) 
// convert back to Javascript Object 
copyOfWindowLocation = JSON.parse(copyOfWindowLocation) 
console.log("Javascript structure - copy:", copyOfWindowLocation)