Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript inheritance without the 'new' keyword

I'm used to using this pattern all over my code, and I like it:

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
    };
})();

However, I have many "widget" objects. "ProfileWidget", "PlayerWidget" etc etc. and there's certain actions that each widget share. So ideally, if we're thinking object-orientally, I want each widget object to inherit some methods from a main "Widget" class.

How can I do this without changing this lovely pattern I've been using?

To be more clear I'd like to be able to do something like this:

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

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

UserWidget.init(); // -> "wow yeah"
like image 409
Luca Matteis Avatar asked Aug 19 '26 02:08

Luca Matteis


1 Answers

Keep in mind these solutions are not what I'd typically reccomend and they are just to satisfy the question.

What about closing over everything so that its accessible from your "sub classes" (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();

Another way (demo) that you might like is to just use proper inheritance, but within the closure and then return one and only one instance of that new function. This way lets you keep User and whatever else an object

// 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();
like image 170
Allen Rice Avatar answered Aug 21 '26 16:08

Allen Rice