我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。
如何正确克隆JavaScript对象?
我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。
如何正确克隆JavaScript对象?
当前回答
老问题的新答案!如果您有幸将ECMAScript 2016(ES6)与Spread Syntax一起使用,这很简单。
keepMeTheSame = {first: "Me!", second: "You!"};
cloned = {...keepMeTheSame}
这为对象的浅层副本提供了一种干净的方法。创建一个深度副本,意味着为每个递归嵌套对象中的每个值创建一个新副本,这需要使用上面更重的解决方案。
JavaScript不断发展。
其他回答
根据MDN:
如果要浅层复制,请使用Object.assign({},a)对于“深度”复制,请使用JSON.parse(JSON.stringify(a))
不需要外部库,但您需要首先检查浏览器兼容性。
这是一个没有Object.assign()陷阱的现代解决方案(不通过引用复制):
const cloneObj = (obj) => {
return Object.keys(obj).reduce((dolly, key) => {
dolly[key] = (obj[key].constructor === Object) ?
cloneObj(obj[key]) :
obj[key];
return dolly;
}, {});
};
克隆对象的简单递归方法。也可以使用lodash.clone。
让克隆=(obj)=>{let obj2=Array.isArray(obj)?[] : {};for(设k为obj){obj2[k]=(obj[k]===“对象”的类型)?克隆(obj[k]):obj[k];}返回obj2;}让w={name:“Apple”,类型:[“Fuji”,“Gala”]};设x=克隆(w);w.name=“橙色”;w.types=[“Navel”];console.log(x);console.log(w);
我在复制对象时遇到问题。这是因为,当您执行以下操作时,您只对对象进行了“引用”,而当稍后更新源对象值时,克隆的复制对象也会更改值,因为它只是一个“引用”。因此,您可以看到源对象上次更改的多个值。
let x = { a: 1 };
let y = x; // y is a reference to x, so if x changes y also changes and v/v
因此,要解决这个问题,请执行以下操作:
let y = JSON.parse(JSON.stringify(x)); //see Note below
防止引用的另一种方法是执行以下操作:
let x = { a: 1 };
let y = Object.assign({}, x); // Object.assign(target, ...sources)
y.a = 2;
console.log(x); // { a: 1 }
console.log(y); // { a: 2 }
注:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#warning_for_deep_clone
正如此链接所示,使用以下代码:
let clone = Object.create(Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj));