是否可以在Javascript中继承特权方法?在下面,Widget成功继承了D
函数,但没有subscribe
。将继承中的第二行更改为f.prototype = new base();
似乎有效,但我知道这种情况很糟糕。有没有干净的方法来做到这一点,还是我必须公开一切? This answer似乎意味着我必须公开这些方法(附加到原型),但我想直接询问。
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);
答案 0 :(得分:1)
this.subscribe = function(key, func) { /* elided */ };
这里是您向当前thisContext
添加方法。
Inherit(Widget, EventRaiser)
在这里你的原型Widget应该使用原型EventRaiser。
您可以做的最好的事情就是不要将this.x
与prototype.y
或者你可以在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,这使得工厂代码更加优雅。
答案 1 :(得分:1)
您的特权方法this.subscribe
仅附加到EventRaiser
的实例。
当你考虑这一行时,这应该是显而易见的:
this.subscribe = function(...) { } ;
仅在调用EventRaiser()
时执行。
如果你没有创建一个EventRaiser
对象,那么属性就不会从那里继承。