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

如何正确克隆JavaScript对象?


当前回答

根据MDN:

如果要浅层复制,请使用Object.assign({},a)对于“深度”复制,请使用JSON.parse(JSON.stringify(a))

不需要外部库,但您需要首先检查浏览器兼容性。

其他回答

本机JS:

const shallowClone = {...originalObj};
const deepClone = JSON.parse(JSON.stringify(originalObj));

使用库:

// Lodash
const shallowClone = _.clone(originalObj);
const deepClone = _. cloneDeep(originalObj);

// JQuery
const shallowClone = jQuery.extend({}, originalObj);
const deepClone = jQuery.extend(true, {}, originalObj);

// Angular
const deepClone = angular.copy(originalObj);

正如此链接所示,使用以下代码:

let clone = Object.create(Object.getPrototypeOf(obj),
 Object.getOwnPropertyDescriptors(obj));

不同的

仅复制顶层:{…object}和object.assign({},object)

让objA={a: “键a”,b:{c: “键c”,}}let objB=Object.assign({},objA);//或{…objB}//更改对象BobjB.a=“更改objA.a(顶部)”console.log(“objA.a(top)无更改:\n”+JSON.stringify(objA,false,2));objB.b.c=“更改应仅适用于objB.b.c,但在objA.b.c中”console.log(“objA.a.c第二级已更改:\n”+JSON.stringify(objA,false,2));

对于深度复制,请使用旧浏览器的structuredClone()2022或JSON.parse(JSON.stringify(object)),无需黑客即可轻松完成。

让objA={a: “键a”,b:{c: “键c”,}}让objB=typeof structuredClone==“函数”?structuredClone(objA):JSON.parse(JSON.stringify(objB));//更改对象BobjB.a=“更改objA.a(顶部)”objB.b.c=“更改应该只针对objB.c,但它在objA.c中”console.log(“objA没有更改:\n”+JSON.stringify(objA,false,2));

在JavaScript中复制对象的方法

使用排列(…)语法使用Object.assign()方法使用JSON.stringify()和JSON.parse()方法

const person = {
    firstName: 'John',
    lastName: 'Doe'
};

// using spread ...
let p1 = {
    ...person
};

// using  Object.assign() method
let p2 = Object.assign({}, person);

// using JSON
let p3 = JSON.parse(JSON.stringify(person));

根据Airbnb JavaScript风格指南,有404位贡献者:

首选对象排列运算符而不是对象。指定为浅层复制物体。使用object rest操作符获取具有特定省略了财产。

// very bad
const original = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 }); // this mutates `original` ಠ_ಠ
delete copy.a; // so does this

// bad
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }

// good
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }

const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

此外,我想提醒您,尽管Airbnb几乎不建议使用对象扩散运算符方法。请记住,Microsoft Edge仍然不支持此2018功能。

ES2016+公司表>>