Search code examples
javascriptjquerymultiple-inheritanceextend

How to implement multiple inheritance using jQuery extend


According to Douglas Crockford I could use something like http://javascript.crockford.com/prototypal.html (with a little bit of tweaking)... but I am interested in jQuery way of doing it. Is it good practice using $.extend ?

I have 4 classes :

            var A = function(){ } 
            A.prototype = {
                name : "A",
                cl : function(){
                    alert(this.name);
                }
            }
            var D = function(){} 
            D.prototype = {
                say : function(){
                    alert("D");
                }
            }

            var B = function(){} //inherits from A
            B.prototype = $.extend(new A(), {
                name : "B"
            });

            var C = function(){} //inherits from B and D
            C.prototype = $.extend(new B(), new D(), {
                name : "C"
            });


            var o = new C();

            alert((o instanceof B) && (o instanceof A) && (o instanceof C)); //is instance of A, B and C 
            alert(o instanceof D); //but is not instance of D

So, i can call every method, property ... from A, B, C and D. Problem comes, when I want to test if o is instance of D? How can I overcome this problem?


Solution

  • Is it good practice using $.extend

    $.extend is useful for singletons but for prototypes is not ideal.

    Using Object.create (or Crockford's polyfill) you can easily create classes like this. I'm using $.extend to simply process the properties and give them default values and the module pattern to keep it well organized. Hope this helps:

    // Helper that makes inheritance work using 'Object.create'
    Function.prototype.inherits = function(parent) {
      this.prototype = Object.create(parent.prototype);
    };
    
    var Person = (function PersonClass() {
    
      var _defaults = {
        name: 'unnamed',
        age: 0
      };
    
      function Person(props) {
        $.extend(this, props, _defaults);
      }
    
      Person.prototype = {
        say: function() {
          return 'My name is '+ this.name;
        }
      };
    
      return Person;
    
    }());
    
    var Student = (function StudentClass(_super) {
    
      Student.inherits(_super); // inherit prototype
    
      var _defaults = {
        grade: 'untested'
      };
    
      function Student(props) {
        _super.apply(this, arguments); // call parent class
        $.extend(this, props, _defaults);
      }
    
      Student.prototype.say = function() {
        return 'My grade is '+ this.grade;
      };
    
      return Student;
    
    }(Person));
    
    var james = new Student({ name: 'James', grade: 5 });
    
    console.log(james instanceof Student); // true
    console.log(james instanceof Person); // true