2013-02-12 27 views
1

在某些大型項目中看到了這種JavaScript模式,它將ClassA的屬性「複製」或「實現」到ClassB,但無法弄清楚調用ClassA的空構造函數的目的是什麼在ClassB的構造函數中使用「.call()」而將ClassB實例作爲「this」綁定?JavaScript模式:將ClassA屬性「複製」到ClassB

var ClassA = function() { 
    //this function is totally empty 
}; 

ClassA.prototype = { 
    jump: function() {...some code...}, 
    dance: function() { 
     if (this.canDance) { 
      alert("dance"); 
     } 
    } 
}; 

ClassA.implementOn = function(targetClassOrObject) { 
    for (var prop in ClassA.prototype) {  
     targetClassOrObject[ prop ] = ClassA.prototype[ prop ]; 
    } 
}; 

var ClassB = function() { 
    this.canDance = true; 
    ClassA.call(this);   // <------------What's the purpose of this line? 
}; 

ClassA.implementOn(ClassB.prototype); 

var instanceOfB = new ClassB(); 
instanceOfB.dance(); 
+0

如果您刪除'ClassB',您會做些什麼? – Mathletics 2013-02-12 16:34:14

+0

如果你的意思是刪除'ClassB'構造函數中的ClassA.call(this);'行,它似乎沒有任何區別。 – 2013-02-12 17:11:27

+0

它只是因爲ClassA構造函數爲空而沒有任何區別。 – apsillers 2013-02-12 17:14:57

回答

2

如果ClassA構造函數爲空,這裏沒有什麼大的驚喜 - call ing ClassA的空構造函數完全沒有任何作用。

你決定要ClassA的構造是非空的,但是,你會看到這條線現在有一個極其重要的作用的時刻:構建ClassB對象還調用ClassA特異性構造行爲的背景下,新構建的ClassB對象,如果ClassBClassA的邏輯「子類」,則這是您所期望的。

(當然,JavaScript沒有適當的「子類」,但顯然這是落實在語言基於類的行爲的一種嘗試。)

0

隨着.call,你可以在調用的方法到您指定的參數改變的this值。作爲上下文,ClassA.call(this)調用ClassA構造函數和ClassB。這允許您在ClassA方法中使用ClassB的屬性。這些方法全部通過ClassA.implementOn複製到ClassB

您會注意到(new ClassA()).dance()什麼都不做,但(new ClassB()).dance()通知"dance",因爲this.canDance爲真。

演示:使用電話ClassB的構造函數的ClassA裏面的空構造的http://jsfiddle.net/5v7xh/

+0

從您的示例中移除'ClassA.call',並查看'dance()'仍然適用於'ClassB'實例。 – robertklep 2013-02-12 17:22:27

1

目的 「.CALL()」

使用該腳本時ClassA不會是空的還在工作。當然,目前它什麼也沒做,但未來可能會改變。因此,實施完整的繼承模式是一種很好的做法,可以在不引入錯誤的情況下更輕鬆地更改代碼。

一旦ClassA更改爲實現在構造函數中設置的自定義特定於實例的屬性,您也希望在ClassB實例上擁有它們。因此,您在初始化期間也會調用ClassB實例上的ClassA構造函數。

1

如果ClassA構造是空的(就像你的榜樣代碼),那麼是的,它什麼都不做。

雖然你看到這種模式的原因是,當它不是。這類似於基於類別OO語言的super調用。

如果您必須在構造函數ClassA中執行一些工作以獲取處於正確狀態的對象,則可能需要在「子類」中執行相同的工作。只是複製原型的屬性可能不夠。

相關問題