Search code examples
javascriptjqueryobjectinheritanceparent

JavaScript inheritance with jQuery - calling parent function


Is there a better method for merging two objects and calling parent functions?

var a = {
   a:1,
   myFunction:function(){
       console.info("a");
   }
}

var b = {
    b:2,
    myFunction:function(){
        console.info("b");
        this.callParent();
    }
}

var obj = {};
$.extend(obj, a);
$.extend(obj, b);
b = obj;
b.superclass = a;

wrapping all functions so "this.callParent" is present

function wrap(func, parent) {
    return function() {
        this.callParent = parent;
        var result = func.apply(this, arguments);
        return (this.callParent), result;
    };
}

with an iteration such as:

$.each(b, function(key, value){
        if(typeof value == "function" && b.superclass && b.superclass[key]){
            b[key] = wrap(value, b.superclass[key]);
        }
});

with an output "b -> a":

b.myFunction();

Demo


Solution

  • Is there a better method for merging two objects and calling parent functions?

    Yes, doing it in one step with a single helper function, instead of that flubbed way with $.extend.

    Notice that jQuery's extend function does not really set up any inheritance, it just can be used for mixins - you shouldn't use the term "inheritance" within reference to that. Also, your objects a and b are definitely no "classes", so please don't name it .superclass. They're singletons at best.

    You can do inheritance in the way you suggested, but notice it is not prototypical inheritance as one would expect in JavaScript.

    function inheritObject(parent, child) {
        for (var p in parent)
            if (!(p in child))
                child[p] = parent[p]; // extend
            else if (typeof child[p] == "function") (function(name, fn) {
                child[name] = function() { // inherit
                    this.callParent = parent[name];
                    var res = fn.apply(this, arguments);
                    delete this.callParent;
                    return res;
                };
            }(p, child[p]));
        return child;
    }
    

    var a = {
       a:1,
       myFunction:function(){
           console.info("a");
       }
    }
    
    var b = inheritObject(a, {
        b:2,
        myFunction:function(){
            console.info("b");
            this.callParent();
        }
    });