我有两个类型相同的对象,我想将其中一个的内容复制到另一个。
const Invoice1 = new InvoiceModel();
const Invoice2 = new InvoiceModel();
现在要具有以下内容:Invoice2 = Invoice1
阅读后:
How do I correctly clone a JavaScript object?
我尝试使用以下任何命令,但所有命令都说在运行时未定义invoice2:
Invoice2 = { ...Invoice1 }; //OR
Invoice2 = Object.assign({}, Invoice1); //OR
Invoice2 = JSON.parse(JSON.stringify(Invoice1));
最后,我通过阅读本文(https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d)使用此功能复制对象的内容:
function CopyObject(src, target) {
for (let prop in src) {
if (src.hasOwnProperty(prop)) {
target[prop] = src[prop];
}
}
return target;
}
我想知道除了使用上面的功能之外,还有没有更清洁的方法?
我已经阅读了很多有关此问题的文章,但所有人都创建了一个新对象。
答案 0 :(得分:7)
我建议在InvoiceModel
的原型中创建一个方法来自动为您完成此操作。
class InvoiceModel {
constructor(num) {
this.num = num
}
duplicate() {
return Object.assign(Object.create(this), this)
}
}
const obj1 = new InvoiceModel(10)
console.log(obj1.num)
const obj1Copy = obj1.duplicate()
console.log(obj1Copy.num)
console.log(obj1Copy === obj1)
答案 1 :(得分:2)
如果对象只是普通的旧数据对象-没有方法或私有状态-您可以按照指定的here使用深对象克隆方法。
但是,从外观上看,您正在使用带有构造函数的类,这意味着您具有方法和状态。这比较棘手,因为这表明您可能依赖重新运行的构造函数,例如在封闭状态中存储私有状态,分配其他资源或依赖某种副作用。在这种情况下,您将需要某种Invoice.prototype.clone
方法,该方法知道如何将状态注入到新实例中,并根据@andrew的回答重新运行该类的构造函数。
我会避免使用注释者建议的语法target = {...src}
克隆对象。一旦拥有非标量引用成员(如子对象或数组),这将给您带来麻烦(因为您将复制指向原始对象的指针,而不是克隆其值)。同样的缺陷也适用于您所使用的CopyObject
函数。
答案 2 :(得分:0)
我已经实现了对象的深层复印机,它不会覆盖target选项中的任何内容,但是如果需要,您也可以实现:
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);
但是,这不会复制未定义为this
成员的“私有”内容。