我有一个董事会成员:
var board = new Board();
我想要修复电路板并在新电路板上运行movePiece
功能:
var newBoard = board;
newBoard.movePiece('4a', '3b');
由于我只是分配它,board
和newBoard
都会有移动的部分。
如何克隆棋盘以创建一个名为newBoard的精确副本,我可以移动该棋子并且原始棋盘将保持不变?
我尝试了几种不同的方法,例如:
Object.assign({}, orig)
和
function clone(orig) {
let origProto = Object.getPrototypeOf(orig);
return Object.assign(Object.create(origProto), orig);
}
答案 0 :(得分:6)
为任意对象创建可靠克隆的唯一方法是在该对象上编写一个方法,该方法接受一个实例并从原始实例的属性创建一个新实例。
这是因为外部代理无法确切知道如何处理每个实例变量(需要分配的内容,需要复制的内容等等),并且也可以拥有私有实例变量。因此,只需编写一个新方法来创建一个新对象并复制相关属性或一个构造函数,该方法将获取另一个对象并执行相同操作。
有可能有一个对象可以将所有属性分配给新实例(如果所有属性都是基元),但通常情况并非如此,因此需要应用更多智能来确定如何最佳分配每个属性到新克隆。而且,一个对象可能有私有实例变量(闭包变量),这些变量也可能必须从其他方法中手动处理。
这是一个相对简单的对象的示例,其中只有一个需要复制的数组。这个支持通过构造函数或克隆方法创建克隆:
function CallbackList(otherObj) {
// if another object is passed to the constructor, then initialize this
// new instance to be a copy
if (otherObj) {
// copy the array from the other instance
this.list = otherObj.list.slice(0);
} else {
// initalize empty list
this.list = [];
}
}
CallbackList.prototype = {
addListener: function(fn) {
this.list.push(fn);
},
removeListener: function(fn) {
for (var i = this.list.length - 1; i >= 0; i--) {
if (this.list[i] === fn) {
this.list.splice(i, 1);
}
}
},
fire: function(/* pass args here */) {
var args = Array.prototype.slice.call(arguments);
this.list.forEach(function(fn) {
fn.apply(null, args);
});
},
clone: function() {
return new CallbackList(this);
}
};
要理解为什么需要专门为您的对象构建的自定义代码来创建克隆,以下是您可能必须以特定于对象的方式处理的实例数据中的一些内容: