什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。


当前回答

Shallow copy one-lineer (ECMAScript 第五版):

var origin = { foo : {} };
var copy = Object.keys(origin).reduce(function(c,k){c[k]=origin[k];return c;},{});

console.log(origin, copy);
console.log(origin == copy); // false
console.log(origin.foo == copy.foo); // true

并下载单线复制(ECMAScript 第六版,2015年):

var origin = { foo : {} };
var copy = Object.assign({}, origin);

console.log(origin, copy);
console.log(origin == copy); // false
console.log(origin.foo == copy.foo); // true

其他回答

我使用npm克隆图书馆,显然它也在浏览器中工作。

https://www.npmjs.com/包装/克隆

let a = clone(b)

在我以前的测试中,速度是我发现的主要担忧。

JSON.parse(JSON.stringify(obj))

是最慢的方式来深化一个对象(它比 jQuery.extend 更慢,深旗定为 10-20% )。

jQuery.extend 是相当快的,当深旗被设置为虚假(shallow clone)。这是一个很好的选择,因为它包含一些额外的逻辑的类型验证,并且不复制未定义的属性,等等,但这也将放缓你下一点。

如果你知道你正在试图克隆的对象的结构,或者可以避免深深的<unk>,你可以写一个简单的为(var i in obj) loop 克隆你的对象,同时检查 hasOwnProperty 它会比 jQuery 快得多。

var clonedObject = {
  knownProp: obj.knownProp,
  ..
}

更新 ES6

Object.assign({}, obj);

没有触摸原型遗产,你可以如下深孤独的物体和岩石;

函数 objectClone(o){ var ot = Array.isArray(o); return o!== null && typeof o === “object”? Object.keys(o).reduce((r,k) => o[k]!== null && typeof o[k] === “object”? (r[k] = objectClone(o[k]),r) : (r[k] = o[k],r), ot?

对于清晰的旧的JavaScript对象,在现代运行时间中克隆对象的一种尝试和真正的好方法是简单的:

var clone = JSON.parse(JSON.stringify(obj));

现在,对于非清晰的JavaScript对象,没有一个真正简单的答案。 事实上,它不能因为JavaScript功能的动态性质和内部对象状态。 深度克隆一个JSON结构与内部功能需要你重建这些功能和它们的内部背景。

我们写了自己的,但我见过的最佳通用方法在这里覆盖:

首頁 〉外文書 〉文學 〉文學 〉 http://davidwalsh.name/javascript-clone

这是有效的吗? Heck 是的. 因为目标是产生一个真正的深复制克隆,那么你将不得不走路的成员的来源对象图。

所以你去吧!两个方法,我认为两者都是有效的。

代码:

// extends 'from' object with members from 'to'. If 'to' is null, a deep clone of 'from' is returned
function extend(from, to)
{
    if (from == null || typeof from != "object") return from;
    if (from.constructor != Object && from.constructor != Array) return from;
    if (from.constructor == Date || from.constructor == RegExp || from.constructor == Function ||
        from.constructor == String || from.constructor == Number || from.constructor == Boolean)
        return new from.constructor(from);

    to = to || new from.constructor();

    for (var name in from)
    {
        to[name] = typeof to[name] == "undefined" ? extend(from[name], null) : to[name];
    }

    return to;
}

测试:

var obj =
{
    date: new Date(),
    func: function(q) { return 1 + q; },
    num: 123,
    text: "asdasd",
    array: [1, "asd"],
    regex: new RegExp(/aaa/i),
    subobj:
    {
        num: 234,
        text: "asdsaD"
    }
}

var clone = extend(obj);