Tuesday, May 10, 2011

jQuery OOP - Inheritance

In my last post I outlined how to achieve some encapsulation behaviors within a jQuery plugin framework. This time I'll be taking a look at inheritance. Specifically I want to able to inherit or override members of one class for use in an inheriting class.

The full objects and examples can be found here.

Super Class

To facilitate inheritance one change had to be made to the super class. The plugin needs a a function (hasFunction) that determines if the plugin responds to a given function.

(function($) {
        //public functions
        var methods = {
                init : function(options) {
                        var defaults = {};
                        $.extend(this, defaults, options);
                        ...
                        return this
                },
                //function to check if plugin responds to function
                hasFunction : function(functionName){
                        return (methods[functionName] !== undefined);
                }
        };                
        $.fn.objectA = function(method) {
                if (methods[method]) {
                        return methods[method].apply(this, 
                               Array.prototype.slice.call(arguments, 1));
                } else if (typeof method === 'object' || !method) {
                        return methods.init.apply(this, arguments);
                } else {
                        $.error('Method ' + method + ' does not exist on jQuery.');
                }
        };
})(jQuery);

Sub Class

Some more work has to be done on the sub class. There is the hasFunction method again, but now that function has to check its parent as well.

Also, In the initialization block two extra changes have to be made. After checking if this plugin responds to a method name, the plugin must check to see if the parent responds, and if so, call the method on the parent plugin. If the plugin is initializing, the parent must be initialized with the same parameters,

(function($) {
        //public functions
        var methods = {
                init : function(options) {
                        var defaults = {};
                        $.extend(this, defaults, options);
                        this.objectBInstance = "Intance B";
                        
                        return this;
                },
                //function to check if plugin responds to function
                hasFunction : function(functionName){
                    //does this or the super class respond to this?
                    return (methods[functionName] !== undefined || this.$super(functionName));
                }
        };        
        /*
                Initialization
        */        
        $.fn.objectB = function(method) {
                if (methods[method]) { //check this class for the method
                        return methods[method].apply(this, 
                                Array.prototype.slice.call(arguments, 1));
                } else if(this.objectA("hasFunction", method)){ //next check the parent
                        //use apply without changing to maintain args
                        return this.objectA.apply(this, arguments);
                }else if (typeof method === 'object' || !method) {//try to init
                        //inherit first inheritance method
                        this.objectA.apply(this, arguments); //inherit from objectA
                        this.$super = this.objectA; //objectA is $super                        
                        return methods.init.apply(this, arguments); //initialize this 
                } else {//if missing from parent/self and not init err out
                        $.error('Method ' + method + ' does not exist on jQuery.');
                }
        };
})(jQuery);

Summary
The inheritance method I outlined above enables public methods and instance variables can be inherited from the super class. In the future I would like to extend this to facilitate multiple inheritance.

No comments:

Post a Comment