[英]How to deep copy (clone) an object with array members in Javascript?
I have a Class Persons
that contains an array of Person
and functions : 我有一类
Persons
,其中包含的阵列Person
及功能:
function Persons() {
this.mItems = []; // Array of Objects Person
}
Persons.prototype = {
calculateScores : function() {
// Do some stuff
}
}
The Class Person
has members and functions : 班级
Person
具有成员和职能:
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
I want to deep copy an instance of Persons
to completely duplicate the Array of Person
. 我想复制一个
Persons
实例以完全复制Person
Array。 The Objects Person must be duplicated. 对象人必须重复。 The functions of the Objects must be kept.
对象的功能必须保留。
JQuery.extend(true, {}, persons)
clones the direct members of Persons
but shallow copies the Person
Objects. 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))
clones the Objects but remove the functions. clonedPersons = JSON.parse(json.stringify(persons))
克隆对象,但删除函数。
persons.mItems[0].calculateScore(); // Does not exists !!!
Thank you for your answers. 谢谢您的回答。
If you're dealing with custom classes, you're going to want to implement custom clone
methods. 如果要处理自定义类,则将要实现自定义
clone
方法。 Generally, in this context, I'd have 2 separate clone
functions, one on the Person
model and one on the Persons
collection. 通常,在这种情况下,我将有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;
}
}
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. 这种方法的优点是它可以将关注点分离开
Person
类不必知道如何克隆单个Person
,而只需知道Person
公开了一个clone
方法。 If Person
adds a new property that should be persisted in the clone, only Person
needs to change. 如果
Person
添加了应保留在克隆中的新属性,则仅需更改Person
。
It's generally an anti-pattern to use generic clone
methods, eg from jQuery or Underscore, in this context. 在这种情况下,使用通用
clone
方法(例如来自jQuery或Underscore的方法)通常是一种反模式。 They'll end up cloning things you don't want, or missing things you do (eg a Person
might eventually have an Address
or some other object that will also need cloning). 他们最终会克隆您不想要的东西,或者丢失您要做的事情(例如,一个
Person
最终可能拥有一个Address
或一些其他需要克隆的对象)。
You can use [].map
and Object.assign
: 您可以使用
[].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;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.