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

如何正确克隆JavaScript对象?


当前回答

这里许多同行针对深度克隆提出的解决方案JSON.parse(JSON.stringify(orig_obj)有几个问题,我发现这些问题如下:

它在复制原始对象中未定义值的条目时丢弃这些条目,如果有一些值,如Infinity、NaN等,它们将在复制时转换为null,如果原始对象中存在Date类型,则它将在克隆对象中字符串化(typeof Date_entry-->string)。

找到了一种克隆对象的有效方法,它在各种场景中都很适合我。请看一看下面的代码,因为它已经解决了JSON.parse(…)的所有上述缺陷,但最终实现了正确的深度克隆:

var orig_obj = {
  string: 'my_str',
  number: 123,
  bool: false,
  nul: null,
  nested : {
    value : true
  },
  nan : NaN,
  date: new Date(), 
  undef: undefined,
  inf: Infinity,
}
console.log("original_obj before modification: ", orig_obj, "\n");
console.log(typeof orig_obj.date, "\n");

var clone_obj = Object.assign({}, orig_obj);

//this below loop will help in deep cloning and solving above issues
for(let prop in orig_obj) {
    if(typeof orig_obj[prop] === "object") {
        if(orig_obj[prop] instanceof Date)
            clone_obj[prop] = orig_obj[prop];
        else {
            clone_obj[prop] = JSON.parse(JSON.stringify(orig_obj[prop]));
        }
    }
}

console.log("cloned_obj before modification: ", orig_obj, "\n");

clone_obj.bool = true;
clone_obj.nested.value = "false";

console.log("original_obj post modification: ", orig_obj, "\n");
console.log("cloned_obj post modification: ", clone_obj, "\n");
console.log(typeof clone_obj.date);

其他回答

对克隆简单对象感兴趣:

JSON.parse(JSON.stringify(JSON_inoriginal));

来源:如何通过引用将JavaScript对象复制到新变量NOT?

根据MDN:

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

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

咨询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中的另一种算法,它可以帮助您实现这一目标。

老问题的新答案!如果您有幸将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对象的克隆。

与许多复制解决方案不同,此克隆在克隆对象中保持原型关系。