Javascript JS:Object.assign() 创建深拷贝还是浅拷贝

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34504682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 16:27:42  来源:igfitidea点击:

JS: Does Object.assign() create deep copy or shallow copy

javascriptobjectdeep-copyshallow-copy

提问by ShivangiBilora

I just came across this concept of

我刚刚遇到了这个概念

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

which creates a copy of original object into the "copy" object. However, my question is, does this way of cloning object create a deep copy or a shallow copy?

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

PS: The confusion is, if it creates a deep copy, then it would be the easiest way to clone an object.

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

采纳答案by Ramanlfc

Forget about deep copy, even shallow copy isn't safe, if the object you're copying has a property with enumerableattribute set to false.

忘记深拷贝,即使是浅拷贝也不安全,如果您正在复制的对象有一个enumerable属性设置为 false 的属性。

MDN :

目录:

The Object.assign() method only copies enumerable and own properties from a source object to a target object

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

take this example

拿这个例子

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

回答by Rish

By using Object.assign(), you are actually doing Shallow Copyof your object. Whenever we do an operation like assigning one object to other, we actually perform a shallow copy, i.e. if OBJ1 is an object, modifying it through another object which is OBJ2 will reflect changes in OBJ1 too.

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

回答by Bihn Kim

It creates a shallow copy, according to this paragraph from MDN:

根据MDN 的这段话,它创建了一个浅拷贝:

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.

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

For the purposes of redux, Object.assign()is sufficient because the state of a redux app only contains immutable values (JSON).

就 redux 而言,Object.assign()就足够了,因为 redux 应用程序的状态只包含不可变值 (JSON)。

回答by Marian07

For small Data structuresI see that JSON.stringify()and JSON.parse()work nice.

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

回答by Manohar Reddy Poreddy

Other answers are complicated.
Some don't answer the question at all.

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

Below worked for me

下面为我​​工作

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

Hope that helps.

希望有帮助。

回答by Saqib Naseeb

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

does a shallow copy which is changing the copy reflect changes in your original object also. So to perform deep copy I would recommend the lodashcloneDeep

做一个改变副本的浅拷贝也反映了原始对象的变化。所以要执行深层复制,我会推荐lodashcloneDeep

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

回答by terrymorse

As mentioned above, Object.assign()will do a shallow clone, fail to copy the source object's custom methods, and fail to copy properties with enumerable: false.

如上所述,Object.assign()将进行浅克隆,无法复制源对象的自定义方法,并且无法复制带有enumerable: false.

Preserving methods and non-enumerable properties takes more code, but not much more.

保留方法和不可枚举的属性需要更多的代码,但不会更多。

This will do a shallow clone of an array or object, copying the source's methods and all properties:

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

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

Example:

例子:

class Custom extends Object {
  myCustom() {}
}

const source = new Custom();
source.foo = "this is foo";
Object.defineProperty(source, "nonEnum", {
  value: "do not enumerate",
  enumerable: false
});
Object.defineProperty(source, "nonWrite", {
  value: "do not write",
  writable: false
});
Object.defineProperty(source, "nonConfig", {
  value: "do not config",
  configurable: false
});

let clone = shallowClone(source);

console.log("source.nonEnum:",source.nonEnum);
// source.nonEnum: "do not enumerate"
console.log("clone.nonEnum:", clone.nonEnum);
// clone.nonEnum: – "do not enumerate"

console.log("typeof source.myCustom:", typeof source.myCustom);
// typeof source.myCustom: – "function"
console.log("typeof clone.myCustom:", typeof clone.myCustom);
// typeof clone.myCustom: – "function"

jsfiddle

提琴手