2011-07-08 26 views
2

克隆簡單的問題我有一個點大約在JavaScript

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()我在接下來的方式

function Point(x, y) { 
    this.x = x; 
    this.y = y; 
    this.clone = function() { 
     function TrickyConstructor() { 
     } 
     TrickyConstructor.prototype = this; 
     return new TrickyConstructor(); 
    }; 
}; 

改寫點但是第二個斷言在我的實現中失敗了。我應該如何重新實現它?

+0

可能重複(http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript) –

回答

4

如果屬性僅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原型鏈將是這樣的:

+-----------+  +-----------+ 
|Instance p2|  |Instance p1| 
|   |----->|x=2  | 
|   |  |y=3  | 
+-----------+  +-----------+ 

所以如果你設置了p1.x = 6它將是:

+-----------+  +-----------+ 
|Instance p2|  |Instance p1| 
|   |----->|x=6  | 
|   |  |y=3  | 
+-----------+  +-----------+ 

只要p2沒有自己的xy屬性,他們將始終指的是原型爲p1的原型。

+0

謝謝,但實際上這個關於一般技術的問題,不僅僅是解決這個特定的問題。 –

+0

@StasKurilin:那麼這個問題已經得到解答:http://stackoverflow.com/questions/4459928/how-to-deep-clone-in-javascript –

+0

雖然他在第二個例子中展示了一般技術...... –

1
function Point(x, y) { 
    this.x = x; 
    this.y = y; 
    this.clone = function() { 
     var newPoint = {}; 
     for (var key in this) { 
      newPoint[key] = this[key]; 
     } 
     return newPoint; 
    }; 
}; 

實施例:http://jsfiddle.net/HPtmk/

[如何深以JavaScript克隆]的
+0

折騰* if(type [this] =='function')繼續; *無需克隆方法。 –

+0

@amadeus - 它不克隆字段,只是分配(在這種情況下分配是必須的,因爲'newPoint'不是以'Point'實例開始的)。它在這種情況下表現爲深層複製,因爲源對象只有兩個基本字段。爲了做一個適當的深層複製,它需要檢查「Object」和「Array」類型並通過它們遞歸。 – aroth

+0

你說得對。但是,爲什麼你會從一個空白對象開始。如果你擁有許多分數很多的方法,那麼這不會浪費空間嗎?爲什麼我不能在評論的開頭插入@aroth? –