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


当前回答

我认为这是最好的解决方案,如果你想通用你的对象克隆算法,它可以用与或没有jQuery,虽然我建议你放弃jQuery的扩展方法,如果你想你克隆的对象有相同的“类”与原始一个。

function clone(obj){
    if(typeof(obj) == 'function')//it's a simple function
        return obj;
    //of it's not an object (but could be an array...even if in javascript arrays are objects)
    if(typeof(obj) !=  'object' || obj.constructor.toString().indexOf('Array')!=-1)
        if(JSON != undefined)//if we have the JSON obj
            try{
                return JSON.parse(JSON.stringify(obj));
            }catch(err){
                return JSON.parse('"'+JSON.stringify(obj)+'"');
            }
        else
            try{
                return eval(uneval(obj));
            }catch(err){
                return eval('"'+uneval(obj)+'"');
            }
    // I used to rely on jQuery for this, but the "extend" function returns
    //an object similar to the one cloned,
    //but that was not an instance (instanceof) of the cloned class
    /*
    if(jQuery != undefined)//if we use the jQuery plugin
        return jQuery.extend(true,{},obj);
    else//we recursivley clone the object
    */
    return (function _clone(obj){
        if(obj == null || typeof(obj) != 'object')
            return obj;
        function temp () {};
        temp.prototype = obj;
        var F = new temp;
        for(var key in obj)
            F[key] = clone(obj[key]);
        return F;
    })(obj);            
}

其他回答

使用今天的JavaScript来克隆一个对象:ECMAScript 2015(以前被称为ECMAScript 6)

var original = {a: 1};

// Method 1: New object with original assigned.
var copy1 = Object.assign({}, original);

// Method 2: New object with spread operator assignment.
var copy2 = {...original};

旧浏览器可能不支持 ECMAScript 2015. 一个常见的解决方案是使用 JavaScript-to-JavaScript 编译器,如 Babel 发行您的 JavaScript 代码的 ECMAScript 5 版本。

正如 @jim-hall 指出的那样,这只是一个微小的副本. 属性属性被复制为参考:更改一个将改变另一个对象/实例的值。

如果沒有任何內建一個,你可以嘗試:

function clone(obj) {
    if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        var temp = new obj.constructor(); //or new Date(obj);
    else
        var temp = obj.constructor();

    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
        }
    }
    return temp;
}

如果您正在使用它,UnderScore.js图书馆有一个克隆方法。

var newObject = _.clone(oldObject);

我知道这是一个古老的帖子,但我以为这可能有助于下一个人,谁在跳动。

只要你不分配一个对象到任何东西,它保留没有参考在记忆中,所以要创建一个对象,你想在其他对象中分享,你将不得不创建一个工厂如下:

var a = function(){
    return {
        father:'zacharias'
    };
},
b = a(),
c = a();
c.father = 'johndoe';
alert(b.father);

使用 Object.create() 获取原型和支持的例子,并使用 for() 圈获取可列的密钥:

function cloneObject(source) {
    var key,value;
    var clone = Object.create(source);

    for (key in source) {
        if (source.hasOwnProperty(key) === true) {
            value = source[key];

            if (value!==null && typeof value==="object") {
                clone[key] = cloneObject(value);
            } else {
                clone[key] = value;
            }
        }
    }

    return clone;
}