我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。

如何正确克隆JavaScript对象?


当前回答

let clone = Object.assign( Object.create( Object.getPrototypeOf(obj)), obj)

ES6解决方案,如果您想要(浅层)克隆类实例而不仅仅是属性对象。

其他回答

使用Lodash:

var y = _.clone(x, true);

使用lodash_.cloneDeep()。

浅拷贝:lodash_.clone()

只需复制参考即可进行浅层复制。

let obj1 = {
    a: 0,
    b: {
        c: 0,
        e: {
            f: 0
        }
    }
};
let obj3 = _.clone(obj1);
obj1.a = 4;
obj1.b.c = 4;
obj1.b.e.f = 100;

console.log(JSON.stringify(obj1));
//{"a":4,"b":{"c":4,"e":{"f":100}}}

console.log(JSON.stringify(obj3));
//{"a":0,"b":{"c":4,"e":{"f":100}}}

深度复制:lodash_.cloneDeep()

取消引用字段:而不是复制对象的引用

let obj1 = {
    a: 0,
    b: {
        c: 0,
        e: {
            f: 0
        }
    }
};
let obj3 = _.cloneDeep(obj1);
obj1.a = 100;
obj1.b.c = 100;
obj1.b.e.f = 100;

console.log(JSON.stringify(obj1));
{"a":100,"b":{"c":100,"e":{"f":100}}}

console.log(JSON.stringify(obj3));
{"a":0,"b":{"c":0,"e":{"f":0}}}

好的,假设你有下面的这个对象,你想克隆它:

let obj = {a:1, b:2, c:3}; //ES6

or

var obj = {a:1, b:2, c:3}; //ES5

答案主要取决于您使用的ECMAscript,在ES6+中,您可以简单地使用Object.assign来执行克隆:

let cloned = Object.assign({}, obj); //new {a:1, b:2, c:3};

或使用如下扩展运算符:

let cloned = {...obj}; //new {a:1, b:2, c:3};

但是如果你使用ES5,你可以使用很少的方法,但JSON.stringify,只需确保你没有使用大量数据来复制,但在很多情况下,这可能是一种简单的方法,比如:

let cloned = JSON.parse(JSON.stringify(obj)); 
//new {a:1, b:2, c:3};, can be handy, but avoid using on big chunk of data over and over

结构化克隆

2022年更新:structuredClone()全局函数已在Node 17、Deno 1.14和大多数主要浏览器中可用(请参阅我可以使用)。

您可以使用与HTML标准相同的结构化克隆机制在领域之间发送数据。

const clone = structuredClone(original);

有关详细信息,请参阅另一个答案。

好的,我知道它有很多答案,但没有人指出,EcmaScript5有赋值方法,在FF和Chrome上工作,它复制可枚举的,并且拥有财产和符号。

对象指定(Object Assign)