jquery class inheritance

后端 未结 6 2011
清歌不尽
清歌不尽 2020-12-24 02:41
var A=function(){
};

$.extend(A.prototype, {
    init:function(){
        alert(\'A init\');
    }
});
var B=function(){

};

$.extend(B.prototype,A.prototype,{
            


        
相关标签:
6条回答
  • 2020-12-24 02:56

    For OO, it's best to look outside jQuery. jQuery is based on collections returned by selectors.

    If you want classes, some choices are Base2, Joose, and JS.Class.

    0 讨论(0)
  • 2020-12-24 03:04

    I use the same pattern and I like its conciseness.

    About the lack of the "super" keyword, that's not really a problem. Thanks to Function.prototype.call() operator, you can call any function within the context of any object. So the sequence to call A.prototype.init() from B.prototype.init() is:

    A.prototype.init.call(this, some parameters ...);

    Also, don't forget that you may call A constructor from B constructor like this:

    B = function(key, name) {
        A.call(this, key);
        this.name = name;
    };
    

    An experimented JS coder will know what happens.

    So to conclude: not perfect but close enough.

    0 讨论(0)
  • 2020-12-24 03:12

    How to invoke parent's methods:

    var B=function(){
        A.call(this);
    };
    
    $.extend(B.prototype,A.prototype,{
            init:function(){
                    A.prototype.init.call(this);
                    alert('B init');
            }
    });
    
    0 讨论(0)
  • 2020-12-24 03:18

    John Resig created a snippet for simple inheritance here. http://ejohn.org/blog/simple-javascript-inheritance/

    he stores the super class to a _super variable so you can call it like such

    this._super();
    

    you can reference his code snippet to get a better idea of what he another helpful post is: http://alexsexton.com/?p=51

    0 讨论(0)
  • 2020-12-24 03:20

    If you don't want to depend on any other libraries, you can do this:

    function A() {}
    A.prototype.foo = function() {};
    
    function B() {
        A.call(this);
        //Or, if there are arguments that need to be passed to A(),
        //this might be preferable:
        //A.apply(this, arguments);
    }
    
    B.prototype = new A();
    
    //Or, if the browser supports ECMAScript 5 and/or you have a shim for Object.create,
    //it would be better to do this:
    B.prototype = Object.create(A.prototype);
    
    $.extend(B.prototype, {
       //set the constructor property back to B, otherwise it would be set to A
       constructor: B,
       bar: function() {}
    });
    

    Make sure to define any properties in the constructor rather than on the prototype, e.g.:

    function A() {
        this.baz = null;
    }
    

    This avoids having unintentionally shared prototype properties.

    There are some libraries that make prototypal inheritance easier:

    • https://github.com/mbrowne/simpleoo.js (my library; its documentation expounds on some of the concepts I've mentioned here)
    • https://github.com/Gozala/selfish
    • https://github.com/Raynos/pd

    Notes:

    • Any time a prototype is replaced, including by extension, it's a best practice to set its constructor property back to the correct constructor. That's why we set B.prototype.constructor to B. If you were replacing A.prototype you should do it like this:

    ...

    A.prototype = {
        constructor: A,
        foo: function() {}
        //other methods...
    }
    
    • B.prototype = Object.create(A.prototype) is preferred over B.prototype = new A() because it helps you detect it early if you forgot to call A() from B()'s constructor; it also allows A() to have required parameters. You'll need a shim for older browsers; the simplest shim (although it doesn't support the full Object.create spec) is at the bottom of this page: http://javascript.crockford.com/prototypal.html.
    0 讨论(0)
  • 2020-12-24 03:20

    I was looking for something similar. None of the answers given really appealed to me, so I finally had a crack at it myself...

    http://jsfiddle.net/tn9upue0/1/

    Example Classes

    • $.Animal() creates a generic animal, with a default of 4 legs, that can be passed a name in it's options, and can describe itself. $.Dog() is a subclass of Animal that goes "woof", and may know some tricks. $.Cat() is a subclass of Animal that goes "meow". $.Bird() is a subclass of Animal that has 2 legs and goes "tweet".

    Class implementation

    • Each animal subclass creates an instance of $.Animal called parent, which can be used later to call methods of the parent. When calling a parent method, context can be important. When it is, the method should be called via $.proxy() passing this as the context.

    Example output

    My name is unknown. I am an animal with 4 legs.

    My name is Rover. I am an animal with 4 legs. I say "woof". I can sit, stay, and roll over.

    My name is Mittens. I am an animal with 4 legs. I say "meow".

    My name is unknown. I am an animal with 2 legs. I say "tweet".

    Sample code

    $.Animal = function (options) {
        return {
            options: options || {},
    
            _getName: function () {
                return this.options.name || 'unknown';
            },
    
            _getLegs: function () {
                return 4;
            },
    
            describe: function () {
                return 'My name is ' + this._getName() + '. I am an animal with ' + this._getLegs() + ' legs.';
            }
        }
    };
    
    $.Dog = function (options) {
        var parent = $.Animal(options);
        return $.extend({}, parent, {
            describe: function () {
                var s = $.proxy(parent.describe, this)() + ' I say  "woof".';
                if (this.options.tricks) {
                    s += ' I can ' + this.options.tricks + '.';
                }
                return s;
            }
        });
    };
    
    $.Cat = function (options) {
        var parent = $.Animal(options);
        return $.extend({}, parent, {
            describe: function () {
                return $.proxy(parent.describe, this)() + ' I say  "meow".';
            }
        });
    };
    
    $.Bird = function (options) {
        var parent = $.Animal(options);
        return $.extend({}, parent, {
            _getLegs: function () {
                return 2;
            },
    
            describe: function () {
                return $.proxy(parent.describe, this)() + ' I say "tweet".';
            }
        });
    };
    
    var animal = $.Animal(),
        rover = $.Dog({name: 'Rover', tricks: 'sit, stay, and roll over'}),
        mittens = $.Cat({name: 'Mittens'}),
        bird = $.Bird();
    $('#out').html(
        animal.describe() + '<br>' +
            rover.describe() + '<br>' +
            mittens.describe() + '<br>' +
            bird.describe()
    );
    
    0 讨论(0)
提交回复
热议问题