我有一个观点
function Point(x, y) {
this.x = x;
this.y = y;
};
如您所见,它是可变的。所以我可以改变它的属性,比如
var p = new Point(2, 3);
p.x = 6;
我想添加克隆方法,以便预期的行为
var p1 = new Point(2, 3);
var p2 = p1.clone();
p1.x = 6;
assert p1 != p2; //first assertion. pseudocode.
assert p2.x == 2; //second assertion. pseudocode.
为了实现clone()
我用下一种方式重写Point
function Point(x, y) {
this.x = x;
this.y = y;
this.clone = function () {
function TrickyConstructor() {
}
TrickyConstructor.prototype = this;
return new TrickyConstructor();
};
};
但是第二个断言对于我的实现失败了。我应该如何重新实现它?
最佳答案
如果属性只有 x
和 y
,我会这样做:
function Point(x, y) {
this.x = x;
this.y = y;
};
Point.prototype.clone = function() {
return new Point(this.x, this.y);
}
请注意,我将 clone
方法附加到 Point.prototype
。这对于下一个方法的工作很重要:
如果没有,您将必须创建一个新实例,并且可能将所有属性复制到新实例:
Point.prototype.clone = function() {
var clone = new Point(this.x, this.y);
for(var prop in this) {
if(this.hasOwnProperty(prop)) {
clone[prop] = this[prop];
}
}
return clone;
}
但这不会深层复制属性。这仅适用于原始值。
如果您确实想要深层复制属性,这可能会变得更加复杂。幸运的是,之前已经有人问过这个问题:How to Deep clone in javascript
解释为什么你的克隆方法不起作用:
p2
的原型(prototype)链如下所示:
+-----------+ +-----------+
|Instance p2| |Instance p1|
| |----->|x=2 |
| | |y=3 |
+-----------+ +-----------+
所以如果你设置p1.x = 6
它将是:
+-----------+ +-----------+
|Instance p2| |Instance p1|
| |----->|x=6 |
| | |y=3 |
+-----------+ +-----------+
只要 p2
没有自己的 x
或 y
属性,它们将始终引用这些属性恰好是 p1
的原型(prototype)。
关于javascript - 关于javascript中克隆的简单问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6623476/