如何在javascript中的两个现有对象之间进行复制

如何在javascript中的两个现有对象之间进行复制,javascript,Javascript,我有两个类型相同的对象,我想将其中一个对象的内容复制到另一个对象 const Invoice1 = new InvoiceModel(); const Invoice2 = new InvoiceModel(); 现在,为了得到如下内容:Invoice2=Invoice1 阅读后: 我尝试使用以下任何命令,但它们都表示在运行时未定义invoice2: Invoice2 = { ...Invoice1 }; //OR Invoice2 = Object.assign({}, Inv

我有两个类型相同的对象,我想将其中一个对象的内容复制到另一个对象

const Invoice1 = new InvoiceModel(); 

const Invoice2 = new InvoiceModel();
现在,为了得到如下内容:Invoice2=Invoice1

阅读后:

我尝试使用以下任何命令,但它们都表示在运行时未定义invoice2:

 Invoice2 = { ...Invoice1 };  //OR

 Invoice2 = Object.assign({}, Invoice1);  //OR

 Invoice2 = JSON.parse(JSON.stringify(Invoice1));
最后,我通过阅读本文()使用此函数复制对象的内容:

我想知道除了使用上述功能,还有什么更干净的方法可以做到这一点吗


我已经阅读了很多关于这个问题的帖子,但是所有的帖子都创建了一个新对象。

我建议在
InvoiceModel
中的原型中创建一个方法,该方法会自动为您执行此操作

类发票模型{
构造函数(num){
this.num=num
}
重复(){
返回Object.assign(Object.create(this),this)
}
}
const obj1=新发票型号(10)
console.log(obj1.num)
常量obj1Copy=obj1.duplicate()
console.log(obj1Copy.num)

console.log(obj1Copy==obj1)
如果对象只是普通的旧数据对象,没有方法或私有状态,则可以按照指定使用深度对象克隆方法

但是,从外观上看,您正在使用带有构造函数的类,这意味着您有方法和状态。这是比较棘手的,因为它表明您可能依赖于正在重新运行的构造函数,例如在闭包中存储私有状态,分配其他资源,或者依赖于某种副作用。在这种情况下,您将需要某种
Invoice.prototype.clone
方法,该方法知道如何将状态注入新实例,并根据@andrew的回答重新运行类的构造函数


我将避免克隆语法为
target={…src}
的对象,一位评论者建议这样做。一旦有了子对象或数组等非标量引用成员,这将给您带来麻烦(因为您将把指针复制到原始对象,而不是克隆它们的值)。同样的缺陷也适用于您选择的
CopyObject
功能。

我已经实现了对象的深度复制器,它不会覆盖目标选项中的任何内容,但是如果您需要,您也可以实现:

var defaults = {
        options: {
                remove: true,
                enable: false,
                instance: {}
        },

        log: {
                warn: true,
                error: true
        }
};

var config = {
        options: {
                remove: false,
                instance: null
        }
};

function applyDefaults(d, t) {
    if ((typeof d !== "object") && (typeof d !== "array")) {
        return d;
    }

    if (t === undefined) {
        if (typeof d === "object") {
            t = {};
        } else if (typeof d === "array") {
            t = [];
        }
    }

    for (var key in d) {
        if (t[key] === undefined) {
            t[key] = d[key];
        } else {
            applyDefaults(d[key], t[key]);
        }
    }
    return t;
}

applyDefaults(defaults, config);
console.log(config);

但是,这不会复制“私有”内容,而不是定义为
的成员我始终使用扩展运算符
..
对象。分配(Invoice2,Invoice1)
是现代的吗way@danh您将需要使用一些多边形填充,因为IES不支持
Object.assign
。前两种方法只能用于浅拷贝,如果要进行深度克隆,则需要使用第三种方法,如果需要,可以使用许多库,例如LoadAsh,因为您无法重新分配const@albertsh-一旦你的类不再表示简单的数据对象,复制就会带来不同的结果。@Andrew,谢谢你的回答,我仍然不能用复制来指定现有的变量,如果您已经创建了:obj1copy=new InvoiceMode,如何使用duplicate,因为Obj1和obj1copy都是全局变量?分配现有变量名和创建现有对象的副本是两件完全不同的事情。也许我误解了你的问题,但我之所以
console.log(obj1Copy==obj1)
是为了证明它们是独立的实体。你现在可以修改一个而不影响另一个。@JimmyBreck McKye是的,这是真的。但基于OPs的例子,这将完成同样的事情,只需要更干净,这就是所要求的
var defaults = {
        options: {
                remove: true,
                enable: false,
                instance: {}
        },

        log: {
                warn: true,
                error: true
        }
};

var config = {
        options: {
                remove: false,
                instance: null
        }
};

function applyDefaults(d, t) {
    if ((typeof d !== "object") && (typeof d !== "array")) {
        return d;
    }

    if (t === undefined) {
        if (typeof d === "object") {
            t = {};
        } else if (typeof d === "array") {
            t = [];
        }
    }

    for (var key in d) {
        if (t[key] === undefined) {
            t[key] = d[key];
        } else {
            applyDefaults(d[key], t[key]);
        }
    }
    return t;
}

applyDefaults(defaults, config);
console.log(config);