如何在Javascript中使用数组成员深度复制(克隆)对象? [英] How to deep copy (clone) an object with array members in 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屋!