2012-11-02 106 views
6

我正在使用Prototypical Inheritance的JavaScript項目。我決定使用它的方式如下:Prototypical Inheritance調用構造函數兩次

var MySuperClass = function (param) { 
    this.prop = param; 
}; 
MySuperClass.prototype.myFunc = function() { 
    console.log(this.prop); 
}; 

var MySubClass = function (param) { 
    MySuperClass.call(this, param); 
}; 
MySubClass.prototype = new MySuperClass(); 
MySubClass.prototype.constructor = MySubClass; 

var obj = new MySubClass('value'); 
obj.myFunc(); 

重點在於繼承。

問題是,如果我在每個類(super和sub)的構造函數中放置一個console.log,超級類會被調用兩次,一旦它被傳遞到子類MySubClass.prototype = new MySuperClass();參數,並且在子類的構造函數中「構造函數被盜」時使用參數。

這可能會導致錯誤,如果我然後嘗試保存這些參數(這意味着我必須添加邏輯來處理空的參數)。

現在,如果我這樣做:

var MySubClass = function (param) { 
    MySuperClass.call(this, param); 
}; 
MySubClass.prototype = MySuperClass; 
MySubClass.prototype.constructor = MySubClass; 

似乎一切都正常工作,但我從來沒有見過任何人這樣做(在我Googl'ing)。

任何人都可以向我解釋第二個是不正確的(它似乎類似於Crockford繼承功能)以及如何解決第一個問題,如果它是請不要兩次?

+0

可能的重複[在這裏使用'new'關鍵字的原因是什麼?](http://stackoverflow.com/questions/12592913/what-is-the-reason-to-use -the-new-keyword-here) – Bergi

回答

7

這樣做是不是正確的解決方案:

MySubClass.prototype = MySuperClass; 

你設置的函數本身爲原型,而不是原型對象,這樣你就不會繼承你所期望。


但你說得對。這樣做確實會調用可能導致問題的構造函數。

MySubClass.prototype = new MySuperClass(); 

的解決方案是使用Object.create成立繼承。它爲您提供了一個從提供的對象繼承的新對象,但不會調用任何構造函數。

MySubClass.prototype = Object.create(MySuperClass.prototype); 

現在你有一個分配給MySubClass.prototypeMySuperClass.prototype繼承的對象,但你從未有過真正調用構造函數。


非ES5兼容實現不支持Object.create,但你可以做一個(部分)墊片它。

if (!Object.create) { 
    Object.create = function(proto) { 
     function F(){} 
     F.prototype = proto; 
     return new F(); 
    }; 
} 

再次,這是不是一個完整的墊片,但它模擬就足以能夠使繼承的對象,而不必調用引用原型對象的構造。

+0

謝謝非常:) – obie

+0

不客氣。 –

相關問題