JS:Object.assign()是否创建深拷贝或浅拷贝

时间:2015-12-29 05:00:05

标签: javascript object deep-copy shallow-copy

我刚刚遇到了这个概念

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

将原始对象的副本创建到" copy"宾语。但是,我的问题是,这种克隆对象的方式是创建深拷贝还是浅拷贝?

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

7 个答案:

答案 0 :(得分:28)

忘记深层复制,即使浅层复制也不安全,如果要复制的对象具有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

答案 1 :(得分:17)

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

答案 2 :(得分:8)

根据this paragraph from MDN

创建一个浅表副本
  

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

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

答案 3 :(得分:5)

对于小型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)

答案 4 :(得分:1)

其他答案很复杂。
有些根本不回答这个问题。

以下为我工作

// orignal object with deep keys
var originalObject = {
    k1: "v1",
    k2: "v2",
    deepObj: {
        k3: "v3",
        k4: "v4"
    }
};

// make copies now
var copy1 = JSON.parse(JSON.stringify(originalObject));
var copy2 = JSON.parse(JSON.stringify(originalObject));

希望有帮助。

答案 5 :(得分:0)

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

执行浅拷贝,该拷贝的变化会反映原始对象的变化。因此,要执行深度复制,我建议使用lodash cloneDeep

import cloneDeep from 'lodash/cloneDeep';
var copy = cloneDeep(originalObject);

答案 6 :(得分:0)

如上所述,if (x.isEmpty()) { return true; } boolean thisNodeEven = x.getValue() % 2 == 0; return thisNodeEven && allE(x.getLeft()) && allE(x.getRight()); 将进行浅层克隆,无法复制源对象的自定义方法,并且无法使用Object.assign()复制属性。

保存方法和不可枚举的属性需要花费更多的代码,但花费的时间并不多。

这将对数组或对象进行浅表克隆,复制源的方法和所有属性:

enumerable: false

示例:

function shallowClone(src) {
  let dest = (src instanceof Array) ? [] : {};

// duplicate prototypes of the source
  Object.setPrototypeOf(dest, Object.getPrototypeOf(src));

  Object.getOwnPropertyNames(src).forEach(name => {
    const descriptor = Object.getOwnPropertyDescriptor(src, name);
    Object.defineProperty(dest, name, descriptor);
  });
  return dest;
}

jsfiddle