我有一个Persons
类,其中包含Person
数组和函数:
function Persons() {
this.mItems = []; // Array of Objects Person
}
Persons.prototype = {
calculateScores : function() {
// Do some stuff
}
}
班级Person
有成员和职能:
function Person(name) {
this.name = name; // Name of the Person
this.score = 0;
}
Person.prototype = {
calculateScore : function() {
// Do some stuff
}
}
我希望程序执行以下操作:
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
的数组。必须复制对象人员。必须保留对象的功能。
JQuery.extend(true, {}, persons)
克隆Persons
的直接成员,但浅层复制Person
个对象。
console.log(persons.mItems[0].name); // Mick : Where is John ?!
console.log(clonedPersons.mItems[0].name); // Mick
clonedPersons = JSON.parse(json.stringify(persons))
克隆对象,但删除了这些函数。
persons.mItems[0].calculateScore(); // Does not exists !!!
感谢您的回答。
答案 0 :(得分:3)
如果您正在处理自定义类,那么您将需要实现自定义clone
方法。通常,在这种情况下,我有2个单独的clone
函数,一个在Person
模型上,另一个在Persons
集合上。
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
,它只需知道{{1}公开Person
方法。如果clone
添加了应在克隆中保留的新属性,则只需要更改Person
。
它通常是使用通用Person
方法的反模式,例如:在这种情况下,来自jQuery或Underscore。他们最终会克隆您不想要的东西,或者遗漏您所做的事情(例如,clone
可能最终会有Person
或其他一些也需要克隆的对象。
答案 1 :(得分:0)
您可以使用[].map
和Object.assign
:
Persons.prototype.clone = function() {
var clone = new Persons();
clone.mItems = this.mItems.map(function(person) {
return Object.assign(new Person, person);
});
return clone;
};