简体   繁体   English

JavaScript inheritance 没有“新”关键字

[英]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. “ProfileWidget”、“PlayerWidget”等,每个小部件共享某些操作。 So ideally, if we're thinking object-orientally, I want each widget object to inherit some methods from a main "Widget" class.所以理想情况下,如果我们正在考虑面向对象,我希望每个小部件 object 从主“小部件”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"

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.您可能喜欢的另一种方法(演示)是仅使用正确的 inheritance,但在闭包内,然后返回该新 function 的一个且仅一个实例。 This way lets you keep User and whatever else an object这种方式可以让您保留用户和其他任何 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();

I decided to use Crockford's object :我决定使用Crockford 的 object

// 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"

This works great for me and I like it!这对我很有用,我喜欢它!

Without using new , you'll have to use the __proto__ property rather than prototype , so this won't work in all browsers.如果不使用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();

Demo: http://jsfiddle.net/mattball/4Xfng/演示: http://jsfiddle.net/mattball/4Xfng/

You could use Object.create(obj) , which I believe is what you're looking for.您可以使用Object.create(obj) ,我相信这就是您要找的。

Here's a simple example of prototyping in JS... For more detail on this topic read "JavaScript: The Good Parts"这是 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

Hope this helps!希望这可以帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM