Javascript наследование и привилегированные функции - PullRequest
1 голос
/ 21 сентября 2011

Можно ли наследовать привилегированные методы в Javascript?Ниже, Widget успешно наследует функцию D, но не subscribe.Изменение второй строки в наследовании на f.prototype = new base();, кажется, работает, но я знаю, что это плохо по разным причинам.Есть ли чистый способ сделать это, или я должен обнародовать все? Этот ответ , кажется, подразумевает, что я должен сделать методы общедоступными (прикрепить к прототипу), но я бы хотел спросить прямо.

    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 ]

1 голос
/ 21 сентября 2011

Ваш привилегированный метод this.subscribe всегда подключен только к экземпляру из EventRaiser.

Это должно быть очевидно, если учесть, что эта строка:

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

выполняется только когда вызывается EventRaiser().

Если вы не создадите объект EventRaiser, это свойство просто никогда не будет наследоваться.

1 голос
/ 21 сентября 2011

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 вокруг.

Приведенный выше код также не выглядит элегантно.Это означает, что вы действительно должны искать другую модель.Например, EventEmitter из node.js имеет явную проверку для объекта this._events, что делает код фабрики более элегантным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...