Javascript继承和特权函数

时间:2011-09-21 16:19:13

标签: javascript javascript-objects

是否可以在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);

2 个答案:

答案 0 :(得分:1)

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

这里是您向当前thisContext添加方法。

Inherit(Widget, EventRaiser)

在这里你的原型Widget应该使用原型EventRaiser。

您可以做的最好的事情就是不要将this.xprototype.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的EventEmitterthis._events对象有一个explicit check,这使得工厂代码更加优雅。

答案 1 :(得分:1)

您的特权方法this.subscribe仅附加到EventRaiser实例

当你考虑这一行时,这应该是显而易见的:

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

仅在调用EventRaiser()时执行。

如果你没有创建一个EventRaiser对象,那么属性就不会从那里继承。