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


当前回答

通过提出新的方法 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])

其他回答

克罗克福德建议(我更喜欢)使用此功能:

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

var newObject = object(oldObject);

它是干净的,工作如预期,你不需要图书馆。


编辑:

这是一个对 Object.create 的聚合物,所以你也可以使用它。

var newObject = Object.create(oldObject);

注意: 如果你使用其中的一些,你可能有问题与某些 iteration谁使用 hasOwnProperty. 因为,创建创造新的空的对象,继承旧的对象. 但它仍然有用和实用的克隆对象。

例如,如果 oldObject.a = 5;

newObject.a; // is 5

但:

oldObject.hasOwnProperty(a); // is true
newObject.hasOwnProperty(a); // is false

我的场景略有不同,我有一個物體,擁有<unk>的物體以及功能,因此,Object.assign() 和 JSON.stringify() 並沒有解決我的問題。

因此,我决定做一个简单的功能,使用内置的方法来复制一个对象,其字面特性,其粘着的对象和功能。

let deepCopy = (target, source) => {
    Object.assign(target, source);
    // check if there's any nested objects
    Object.keys(source).forEach((prop) => {
        /**
          * assign function copies functions and
          * literals (int, strings, etc...)
          * except for objects and arrays, so:
          */
        if (typeof(source[prop]) === 'object') {
            // check if the item is, in fact, an array
            if (Array.isArray(source[prop])) {
                // clear the copied referenece of nested array
                target[prop] = Array();
                // iterate array's item and copy over
                source[prop].forEach((item, index) => {
                    // array's items could be objects too!
                    if (typeof(item) === 'object') {
                        // clear the copied referenece of nested objects
                        target[prop][index] = Object();
                        // and re do the process for nested objects
                        deepCopy(target[prop][index], item);
                    } else {
                        target[prop].push(item);
                    }
                });
            // otherwise, treat it as an object
            } else {
                // clear the copied referenece of nested objects
                target[prop] = Object();
                // and re do the process for nested objects
                deepCopy(target[prop], source[prop]);
            }
        }
    });
};

下面是测试代码:

let a = {
    name: 'Human', 
    func: () => {
        console.log('Hi!');
    }, 
    prop: {
        age: 21, 
        info: {
            hasShirt: true, 
            hasHat: false
        }
    },
    mark: [89, 92, { exam: [1, 2, 3] }]
};

let b = Object();

deepCopy(b, a);

a.name = 'Alien';
a.func = () => { console.log('Wassup!'); };
a.prop.age = 1024;
a.prop.info.hasShirt = false;
a.mark[0] = 87;
a.mark[1] = 91;
a.mark[2].exam = [4, 5, 6];

console.log(a); // updated props
console.log(b);

对于效率相关的担忧,我认为这是我遇到的问题的最简单和最有效的解决方案,我会欣赏任何关于这个算法的评论,这可能会使它更有效。

function clone(obj)
 { var clone = {};
   clone.prototype = obj.prototype;
   for (property in obj) clone[property] = obj[property];
   return clone;
 }

Lodash 有一个可爱的 _.cloneDeep(值) 方法:

var objects = [{ 'a': 1 }, { 'b': 2 }];

var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
var clone = function() {
    var newObj = (this instanceof Array) ? [] : {};
    for (var i in this) {
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        }
        else
        {
            newObj[i] = this[i];
        }
    }
    return newObj;
}; 

Object.defineProperty( Object.prototype, "clone", {value: clone, enumerable: false});