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


当前回答

class Handler { static deepCopy (obj) { if (Object.prototype.toString.call(obj) === '[object Array]') { const result = []; for (let i = 0, len = obj.length; i < len; i++) { result[i] = Handler.deepCopy(obj[i]); } return result; } else if (Object.prototype.toString.call(obj) === '[object Object]') { const result = {}; for (let prop in obj) { result[prop] = Handler.deepCopy(obj[prop]); } return result; } return obj; } }

其他回答

这通常不是最有效的解决方案,但它是我需要的。

function clone(obj, clones) {
    // Makes a deep copy of 'obj'. Handles cyclic structures by
    // tracking cloned obj's in the 'clones' parameter. Functions 
    // are included, but not cloned. Functions members are cloned.
    var new_obj,
        already_cloned,
        t = typeof obj,
        i = 0,
        l,
        pair; 

    clones = clones || [];

    if (obj === null) {
        return obj;
    }

    if (t === "object" || t === "function") {

        // check to see if we've already cloned obj
        for (i = 0, l = clones.length; i < l; i++) {
            pair = clones[i];
            if (pair[0] === obj) {
                already_cloned = pair[1];
                break;
            }
        }

        if (already_cloned) {
            return already_cloned; 
        } else {
            if (t === "object") { // create new object
                new_obj = new obj.constructor();
            } else { // Just use functions as is
                new_obj = obj;
            }

            clones.push([obj, new_obj]); // keep track of objects we've cloned

            for (key in obj) { // clone object members
                if (obj.hasOwnProperty(key)) {
                    new_obj[key] = clone(obj[key], clones);
                }
            }
        }
    }
    return new_obj || obj;
}

自行车测试...

a = []
a.push("b", "c", a)
aa = clone(a)
aa === a //=> false
aa[2] === a //=> false
aa[2] === a[2] //=> false
aa[2] === aa //=> true

功能测试...

f = new Function
f.a = a
ff = clone(f)
ff === f //=> true
ff.a === a //=> false

英格兰

好吧,如果你使用角,你也可以这样做。

var newObject = angular.copy(oldObject);

只是因为我没有看到AngularJS提到并认为人们可能想知道......

angular.copy 还提供深复制对象和序列的方法。

通过这个漫长的答案列表,几乎所有的解决方案都被覆盖了,除了我知道的一个。

JSON.parse(JSON.stringify( obj ); 通过 history.state 与 pushState 或 replaceState Web Notifications API 但这有缺点请求用户的许可。 通过对象进行自己的回归路径,以复制每个级别. 答案我没有看到 -> 使用 ServiceWorkers. 邮件(对象)在页面和 ServiceWorker 脚本之间返回和返回将是深的克隆

通过提出新的方法 Object.fromEntries(),它支持一些浏览器的更新的版本(参考)。

const obj = { key1: {key11: “key11”, key12: “key12”, key13: {key131: 22}}, key2: {key21: “key21”, key22: “key22”}, key3: “key3”, key4: [1,2,3, {key: “value”} } const cloneObj = (obj) => { if (Object(obj)!== obj) return obj; other if (Array.isArray(obj)) return obj.map(cloneObj); return Object.fromEntries(Object.entries(obj).map(([k,v])