Наследование JavaScript без ключевого слова «new» - PullRequest
3 голосов
/ 30 июня 2011

Я привык использовать этот шаблон во всем коде, и мне нравится:

var UserWidget = (function(){
    var url = "/users",
        tmpl = "#users li", $tmpl;

    function load() {
        $tmpl = $(tmpl);
        $.getJSON(url, function(json){
            $.each(json, function(i, v) {
                appendUser(v);            
            });
        });
    }

    ...
    return {
        load: load
    };
})();

Однако у меня много объектов "виджетов". "ProfileWidget", "PlayerWidget" и т. Д. И т. Д., И есть определенные действия, которые разделяет каждый виджет. Поэтому в идеале, если мы думаем объектно-ориентированно, я хочу, чтобы каждый объект виджета наследовал некоторые методы из основного класса "Widget".

Как я могу сделать это, не меняя этот прекрасный шаблон, который я использовал?

Чтобы быть более ясным, я хотел бы иметь возможность сделать что-то вроде этого:

var Widget = (function() {
    function init() {
        console.log("wow yeah");
    }
})();

// have UserWidget inherit somehow the Widget stuff
var UserWidget = (function() { ...

UserWidget.init(); // -> "wow yeah"

Ответы [ 5 ]

3 голосов
/ 30 июня 2011

Имейте в виду, что эти решения - не то, что я обычно рекомендую, и они просто для того, чтобы удовлетворить вопрос.

Как насчет закрытия всего, чтобы оно было доступно из ваших "подклассов" ( demo )

var Widget = (function () {

    var init = function () {
        console.log("wow yeah");
    };

    var User = (function () {

        var load = function () {
            init();
        };

        return {
            'load': load
        };
    } ());

    return { 'User': User };
} ());

// Usage: This loads a user and calls init on the "base"
Widget.User.load();

Другой способ ( demo ), который вам может понравиться, - это просто использовать правильное наследование, но внутри замыкания, а затем вернуть один и только один экземпляр этой новой функции. Этот способ позволяет сохранить пользователя и все остальное объект

// Closing around widget is completely unneccesarry, but 
//    done here in case you want closures and in case you 
//    dont want another instance of widget
var Widget = (function () {

    // definition that we'll end up assigning to Widget
    function widget() {
           console.log("base ctor");
    }

    // sample method
    widget.prototype.init = function () {
        console.log("wow yeah");
    };

    // put widget in Widget
    return widget;
} ());

var User = (function () {

    function user() { }
    user.prototype = new Widget();

    // TODO: put your User methods into user.prototype

    return new user();
} ());

var Player = (function () {

    function player() { }
    player.prototype = new Widget();

    // TODO: put your Player methods into player.prototype

    return new player();

} ());

User.init();
Player.init();
2 голосов
/ 01 июля 2011

Я решил использовать объект Крокфорда :

// function from Douglas Crockford, comments from me
function object(o) {
    // define a new function
    function F() {}
    // set the prototype to be the object we want to inherit 
    F.prototype = o;
    // return a new instance of that function, copying the prototype and allowing us to change it without worrying about modifying the initial object
    return new F();
}

// Usage:
var Widget = (function() {
    function init() {
        console.log("wow yeah");
    }
    return {
        init: init 
    };
})();

var UserWidget = (function() {
    var self = object(Widget); // inherit Widget
    function priv() {}
    self.pub = "boom";
    ...

    return self;
})();

UserWidget.init() // -> "wow yeah"

Это прекрасно работает для меня, и мне это нравится!

0 голосов
/ 30 июня 2011

Вот простой пример создания прототипов в JS ... Подробнее об этой теме читайте в разделе «JavaScript: хорошие части»

// widget definition
var Widget = {
    init: function () {
        alert('wow yeah!');
    }
};
// user widget definition
var UserWidget = function () { };
UserWidget.prototype = Widget;
UserWidget.prototype.load = function () { alert('your code goes here'); }

// user widget instance
var uw = new UserWidget();
uw.init(); // wow yeah!
uw.load(); // your code goes here

Надеюсь, это поможет!

0 голосов
/ 30 июня 2011

Вы можете использовать Object.create (obj) , который, я считаю, именно то, что вы ищете.

0 голосов
/ 30 июня 2011

Без использования new вам придется использовать свойство __proto__ вместо prototype, поэтому это не будет работать во всех браузерах.

var Widget = {
    init: function () {
        console.log("wow yeah");
    }
};

var UserWidget = (function(){
    var url = "/users",
        tmpl = "#users li",
        $tmpl;

    function load() {
        $tmpl = $(tmpl);
        $.getJSON(url, function(json){
            $.each(json, function(i, v) {
                appendUser(v);            
            });
        });
    }

    return {
        load: load
    };
})();

UserWidget.__proto__ = Widget;

UserWidget.init();

Демо: http://jsfiddle.net/mattball/4Xfng/

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