2011-09-21 65 views
1

是否有可能在Javascript中繼承特權方法?在下面,Widget成功繼承D函數,但不是subscribe。將第二行繼承爲f.prototype = new base();似乎可行,但我知道這是由於種種原因造成的。有沒有一種乾淨的方式來做到這一點,還是我必須公開一切? This answer似乎暗示我必須公開方法(附加到原型),但我想直接詢問。Javascript繼承和特權函數

function EventRaiser() { 
     var events = {}; 
     this.subscribe = function(key, func) { /* elided */ }; 
    } 
    EventRaiser.prototype.D = function() { alert("D"); }; 

    function Widget() { } 

    function Inherit(sub, base) { 
     function f() { } 
     f.prototype = base.prototype; 
     sub.prototype = new f(); 
     sub.prototype.constructor = sub; 
    } 

    Inherit(Widget, EventRaiser); 

回答

1

this.subscribe = function(key, func) { /* elided */ };

這裏你添加一個方法到當前thisContext

Inherit(Widget, EventRaiser)

這裏您的Saling原型的Widget要消耗原型EventRaiser。

你能做的最好是不要用prototype.y

混合this.x或者你可以撥打EventRaiser.call(this)function Widget() { }但是這是很糟糕的風格。

如果你要使用的遺傳模式,我建議你使用Object.create & pd

// prototype 
var EventRaiser = { 
    D: function() { alert("D"); }, 
    subscribe: function(key, func) { ... } 
}; 
// factory 
var eventRaiser = function _eventRaiser(proto) { 
    proto = proto || EventRaiser; 
    return Object.create(proto, pd({ 
     events: {} 
    })); 
}; 

// prototype 
var Widget = { 
    ...  
}; 
// factory 
var widget = function _widget() { 
    var o = eventRaiser(pd.merge(Widget, EventRaiser)); 
    Object.defineProperties(o, pd({ 
     ... 
    }); 
    return o; 
}; 

或者,如果你堅持Widget應該EventRaiser

var Widget = Object.create(EventRaiser, pd({ 
    ... 
}); 
var widget = function _widget() { 
    var o = eventRaiser(Widget); 
    Object.defineProperties(o, pd({ 
     ... 
    }); 
    return o; 
} 

繼承推薦這種模式的原因是原型和工廠的明確分離。這使您可以在不處理工廠的情況下與原型進行交互。通過使用new關鍵字,您可以渾濁這些水域(如您的代碼所示),並且您也傾向於繞着this左右。

上面的代碼看起來並不漂亮。這意味着你真的很樂意尋找不同的模式。例如,來自node.js的EventEmitter對於this._events對象具有explicit check,這使得工廠代碼更優雅。

+0

'EventRaiser.call(this)'是我認爲我需要的。爲什麼這種不好的風格?鏈接到你的基礎ctor是OO Languages的常見做法,甚至這個JS樣本也可以這樣做http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html –

+0

@AdamRackis沒有基礎構造函數的概念。您在JavaScript中模擬經典的OO和Java。這是不好的風格 – Raynos

1

您的特權方法this.subscribe只能附加到實例EventRaiser

this.subscribe = function(...) { } ; 

EventRaiser()被稱爲只會被執行:

當你考慮到這條線這應該是顯而易見的。

如果您沒有創建一個EventRaiser對象,那麼屬性根本就不會從那裏繼承。