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

如何正确克隆JavaScript对象?


当前回答

咨询http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#safe-为W3C的“安全传递结构化数据”算法传递结构化数据,该算法旨在由浏览器实现,用于将数据传递给例如web工作者。然而,它有一些限制,因为它不处理函数。看见https://developer.mozilla.org/en-US/docs/DOM/The_structured_clone_algorithm获取更多信息,包括JS中的另一种算法,它可以帮助您实现这一目标。

其他回答

如果对象中没有循环依赖关系,我建议使用其他答案之一或jQuery的复制方法,因为它们看起来都很有效。

如果存在循环依赖关系(即,两个子对象彼此链接),那么你就有点糟糕了,因为(从理论角度)没有办法优雅地解决这个问题。

老问题的新答案!如果您有幸将ECMAScript 2016(ES6)与Spread Syntax一起使用,这很简单。

keepMeTheSame = {first: "Me!", second: "You!"};
cloned = {...keepMeTheSame}

这为对象的浅层副本提供了一种干净的方法。创建一个深度副本,意味着为每个递归嵌套对象中的每个值创建一个新副本,这需要使用上面更重的解决方案。

JavaScript不断发展。

可以使用rest运算符克隆阵列或对象

let myObj = {1: 100, 'a': 200};

let clone = {...myObj}; 

clone.a = 300;

console.log(clone.a) // Output :- 300
console.log(myObj.a) // Output :- 200

一个特别不优雅的解决方案是使用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

我已经在标量对象的情况下尝试过这一点,它对我很有用:

function binder(i) {
  return function () {
    return i;
  };
}

a=1;
b=binder(a)(); // copy value of a into b

alert(++a); // 2
alert(b); // still 1

当做