如何在JavaScript中的两个现有对象之间复制

时间:2019-05-28 18:19:40

标签: javascript

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

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;
}

我想知道除了使用上面的功能之外,还有没有更清洁的方法?

我已经阅读了很多有关此问题的文章,但所有人都创建了一个新对象。

3 个答案:

答案 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成员的“私有”内容。