我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。
如何正确克隆JavaScript对象?
我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。
如何正确克隆JavaScript对象?
当前回答
您可以使用函数闭包来获得深度复制的所有好处,而无需深度复制。这是一个非常不同的范例,但效果很好。不要试图复制现有对象,只要在需要时使用函数实例化新对象即可。
首先,创建一个返回对象的函数
function template() {
return {
values: [1, 2, 3],
nest: {x: {a: "a", b: "b"}, y: 100}
};
}
然后创建一个简单的浅层复制函数
function copy(a, b) {
Object.keys(b).forEach(function(key) {
a[key] = b[key];
});
}
创建一个新对象,并将模板的财产复制到其中
var newObject = {};
copy(newObject, template());
但上述复制步骤不是必需的。您需要做的就是:
var newObject = template();
现在您有了一个新对象,请测试它的财产:
console.log(Object.keys(newObject));
这将显示:
["values", "nest"]
是的,这些是newObject自己的财产,而不是对另一个对象上财产的引用。让我们检查一下:
console.log(newObject.nest.x.b);
这将显示:
"b"
newObject获得了模板对象的所有财产,但没有任何依赖链。
http://jsbin.com/ISUTIpoC/1/edit?js安慰
我添加此示例是为了鼓励一些讨论,因此请添加一些评论:)
其他回答
在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));
如果您正在使用TypeScript,需要支持较旧的web浏览器(因此无法使用Object.assign),并且没有使用内置有克隆方法的库,那么您可以在几行代码中使自己成为组合助手。它结合了对象,如果只有一个,就克隆它。
/** Creates a new object that combines the properties of the specified objects. */
function combine(...objs: {}[]) {
const combined = {};
objs.forEach(o => Object.keys(o).forEach(p => combined[p] = o[p]));
return combined;
}
根据MDN:
如果要浅层复制,请使用Object.assign({},a)对于“深度”复制,请使用JSON.parse(JSON.stringify(a))
不需要外部库,但您需要首先检查浏览器兼容性。
老问题的新答案!如果您有幸将ECMAScript 2016(ES6)与Spread Syntax一起使用,这很简单。
keepMeTheSame = {first: "Me!", second: "You!"};
cloned = {...keepMeTheSame}
这为对象的浅层副本提供了一种干净的方法。创建一个深度副本,意味着为每个递归嵌套对象中的每个值创建一个新副本,这需要使用上面更重的解决方案。
JavaScript不断发展。
这是一个没有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;
}, {});
};