我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。
如何正确克隆JavaScript对象?
我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。
如何正确克隆JavaScript对象?
当前回答
如果在对象中不使用Dates、functions、undefined、regExp或Infinity,那么一个非常简单的一行代码就是JSON.parse(JSON.stringify(object)):
常量a={string:'字符串',编号:123,bool:false,nul:空,date:new date(),//字符串化undef:未定义,//丢失inf:无限,//强制为“null”}控制台日志(a);console.log(类型a.date);//日期对象constclone=JSON.parse(JSON.stringify(a));console.log(克隆);console.log(clone.date的类型);//.toISOString()的结果
这适用于包含对象、数组、字符串、布尔值和数字的所有类型的对象。
另请参阅本文,了解浏览器的结构化克隆算法,该算法在向工作人员发布消息时使用。它还包含一个用于深度克隆的功能。
其他回答
对于深度复制和克隆,JSON.stringify然后JSON.parse对象:
obj = { a: 0 , b: { c: 0}};
let deepClone = JSON.parse(JSON.stringify(obj));
obj.a = 5;
obj.b.c = 5;
console.log(JSON.stringify(deepClone)); // { a: 0, b: { c: 0}}
一个特别不优雅的解决方案是使用JSON编码对没有成员方法的对象进行深度复制。方法是对目标对象进行JSON编码,然后通过对其进行解码,获得所需的副本。您可以解码任意次数,以制作任意数量的副本。
当然,函数不属于JSON,因此这只适用于没有成员方法的对象。
这种方法非常适合我的用例,因为我将JSON blob存储在一个键值存储中,并且当它们在JavaScript API中作为对象公开时,每个对象实际上都包含对象的原始状态的副本,因此我们可以在调用方对公开的对象进行变异后计算增量。
var object1 = {key:"value"};
var object2 = object1;
object2 = JSON.stringify(object1);
object2 = JSON.parse(object2);
object2.key = "a change";
console.log(object1);// returns value
老问题的新答案!如果您有幸将ECMAScript 2016(ES6)与Spread Syntax一起使用,这很简单。
keepMeTheSame = {first: "Me!", second: "You!"};
cloned = {...keepMeTheSame}
这为对象的浅层副本提供了一种干净的方法。创建一个深度副本,意味着为每个递归嵌套对象中的每个值创建一个新副本,这需要使用上面更重的解决方案。
JavaScript不断发展。
我最喜欢的优雅JS对象克隆解决方案是
function CloneObject() {}
function cloneObject(o) {
CloneObject.prototype = o;
return new CloneObject();
}
使用cloneObject(object)获取JS对象的克隆。
与许多复制解决方案不同,此克隆在克隆对象中保持原型关系。
2020年7月6日更新
有三(3)种方法可以在JavaScript中克隆对象。由于JavaScript中的对象是引用值,因此不能简单地使用=进行复制。
方法如下:
const food = { food: 'apple', drink: 'milk' }
// 1. Using the "Spread"
// ------------------
{ ...food }
// 2. Using "Object.assign"
// ------------------
Object.assign({}, food)
// 3. "JSON"
// ------------------
JSON.parse(JSON.stringify(food))
// RESULT:
// { food: 'apple', drink: 'milk' }
这可以用作参考摘要。