javascript - 关于javascript中克隆的简单问题

标签 javascript clone deep-copy

我有一个观点

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();
    };
};

但是第二个断言对于我的实现失败了。我应该如何重新实现它?

最佳答案

如果属性只有 xy,我会这样做:

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 没有自己的 xy 属性,它们将始终引用这些属性恰好是 p1 的原型(prototype)。

关于javascript - 关于javascript中克隆的简单问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6623476/

相关文章:

javascript - 重新加载页面后,如何使用 twitter bootstrap 使当前选项卡保持事件状态?

javascript - 有没有办法从片段重建有效的 HTML 结构?

ruby - 在 ruby​​ 1.9.3. 中,: object-instance. 克隆创建的对象怎么找不到原始对象可以找到的方法?

java - java中的深度 copy-and-swap 子树

c++ - 如何实现两个类自动判定深拷贝和浅拷贝?

javascript - While LOOP - PHP - 动态关闭括号

javascript - 仅在单击元素而不是其子元素时触发事件

java - Cloneable 抛出 CloneNotSupportedException

c# - 如何深度克隆 C# 中的互连对象?

c# - 从委托(delegate)构造委托(delegate)。新的委托(delegate)指向什么?