Наследование объектов - PullRequest
       5

Наследование объектов

2 голосов
/ 24 ноября 2011
function Foo() {
    this.SayFoo = function() {
        console.log('Foo');
    };
}

function Bar() {
    this.SayBar = function() {
        console.log('Bar');
    };
}

Foo.prototype = new Bar();

var fooBar = new Foo();
fooBar.SayBar();

Это, очевидно, работает, но правильно ли это сделать?

Есть ли способ использовать jQuery $.extend или что-то подобное для достижения тех же результатов наследования?

Включение других платформ помимо jQuery в этом случае не вариант.

Ответы [ 2 ]

1 голос
/ 24 ноября 2011

На самом деле в JavaScript существует несколько способов наследования: неоклассический, прототипный и функциональный.У Дугласа Крокфорда нет ничего, кроме плохих слов о неоклассическом наследовании - метод, который вы описали выше, и метод, который большинство разработчиков на Java / C # считают наиболее естественным.Причина кроется в неловких вещах, которые вы должны сделать, чтобы сделать это правильно - установка прототипа, установка конструктора и т. Д. Кроме того, установка прототипа для new экземпляра родительского класса, как у вас было выше, обычнорешительно нахмурился, я полагаю, потому что это усложняет обработку параметров с помощью базового ctor.

Если вы действительно продали неоклассический метод, вот отличная ссылка , которая действительно перебирает его.

Ключевая часть, которую я воспроизвожу для вас здесь:

function Inherit(sub,super){
    var thinF = function(){};
    thinF.prototype = super.prototype;
    sub.prototype = new thinF();
    sub.prototype.constructor = sub;
    sub.super = super.prototype;
    if( super.prototype.constructor == Object.prototype.constructor ){
        super.prototype.constructor = super;
    }
}

FWIW Вот пример функционального наследования, который также подчеркивает то, что вы не получаете с неоклассическим методом:инкапсуляция / сокрытие информации.

function eventRaiser(protectedStuff) {
    protectedStuff = protectedStuff || {}; 
    var that = {};
    var events = {};  //private

    protectedStuff.raise = function(key) {
        if (!events[key]) return;
            for (var i = 0; i < events[key].funcs.length; i++)
                events[key].funcs[i].apply(null, Array.prototype.slice.call(arguments, 1));
    };

    that.subscribe = function(key, func) {
        if (!events[key])
            events[key] = { name: key, funcs: [] };
        events[key].funcs.push(func);
    };

    return that;
}        

function widget() {
    var protectedStuff = {};
    var that = eventRaiser(protectedStuff);

    that.doSomething = function() { 
        alert("doing something"); 
        protectedStuff.raise("doStuffEvent");
    };

    return that;
}

$(function() {
    var w = widget();
    w.subscribe("doStuffEvent", function(){ alert("I've been raised"); });
    w.doSomething();

    w.protectedStuff.raise("doStuffEvent"); //error!!!!!  raise is protected
    w.raise("doStuffEvent"); //and this obviously won't work
});
0 голосов
/ 24 ноября 2011

Да, установка prototype для экземпляра является правильным способом сделать это.

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