如何在Javascript中使用数组成员深度复制(克隆)对象? [英] How to deep copy (clone) an object with array members in Javascript?

查看:92
本文介绍了如何在Javascript中使用数组成员深度复制(克隆)对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Class Persons ,其中包含一个 Person 和函数:

I have a Class Persons that contains an array of Person and functions :

function Persons() {
  this.mItems = []; // Array of Objects Person
}

Persons.prototype = {
  calculateScores : function() {
    // Do some stuff
  }
}

Class Person 有会员和函数:

The Class Person has members and functions :

function Person(name) {
  this.name = name; // Name of the Person
  this.score = 0;
}

Person.prototype = {
  calculateScore : function() {
    // Do some stuff
  }
}

我希望程序执行以下操作:

I want that the program does the following things :

var persons = new Persons();
var person0 = new Person("John");
var person1 = new Person("Sam");
persons.mItems.push(person0);
persons.mItems.push(person1);

// Completely clone the original Objects
clonedPersons = persons.clone(); // I am looking for a clone() function

// Modify an item in the cloned Objects
clonedPersons.mItems[0].name = "Mick";

// Check that the original Objects have not been modified
console.log(persons.mItems[0].name); // John : Not modified
console.log(clonedPersons.mItems[0].name); // Mick



问题



我想深度复制 Persons 的实例,以完全复制 Person 的数组。必须复制对象人员。必须保留对象的功能。

Question

I want to deep copy an instance of Persons to completely duplicate the Array of Person. The Objects Person must be duplicated. The functions of the Objects must be kept.

JQuery.extend(true,{},persons)克隆 Persons 的直接成员,但浅层复制 Person 对象。

JQuery.extend(true, {}, persons) clones the direct members of Persons but shallow copies the Person Objects.

console.log(persons.mItems[0].name); // Mick : Where is John ?!
console.log(clonedPersons.mItems[0].name); // Mick



JSON.parse(json.stringify())



clonedPersons = JSON.parse(json.stringify(persons))克隆对象但删除函数。

JSON.parse(json.stringify())

clonedPersons = JSON.parse(json.stringify(persons)) clones the Objects but remove the functions.

persons.mItems[0].calculateScore(); // Does not exists !!!

感谢您的回答。

推荐答案

如果您正在处理自定义类,那么您将需要实现自定义 clone 方法。通常,在这种情况下,我有2个单独的克隆函数,一个在 Person 模型上,另一个在集合。

If you're dealing with custom classes, you're going to want to implement custom clone methods. Generally, in this context, I'd have 2 separate clone functions, one on the Person model and one on the Persons collection.

Persons.prototype = {
  clone: function() {
    var clone = new Persons();
    clone.mItems = this.mItems.map(function(person) {
        return person.clone();
    });
    return clone;
  }
}

Person.prototype = {
  clone: function() {
    var clone = new Person(this.name);
    clone.score = this.score;
    return clone;
  }
}

这种方法的优势在于它将问题分开 - Person 类不必知道如何克隆单个 Person ,它只需要知道 Person 公开 clone 方法。如果 Person 添加了一个应该保留在克隆中的新属性,则只需要更改 Person

The advantage to this approach is that it separates the concerns - the Person class doesn't have to know how to clone a single Person, it only has to know that Person exposes a clone method. If Person adds a new property that should be persisted in the clone, only Person needs to change.

使用泛型 clone 方法通常是一种反模式,例如在这种情况下,来自jQuery或Underscore。他们最终会克隆你不想要的东西,或者丢失你所做的事情(例如 Person 最终可能会有地址或其他一些还需要克隆的对象。

It's generally an anti-pattern to use generic clone methods, e.g. from jQuery or Underscore, in this context. They'll end up cloning things you don't want, or missing things you do (e.g. a Person might eventually have an Address or some other object that will also need cloning).

这篇关于如何在Javascript中使用数组成员深度复制(克隆)对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆