Search code examples
javascriptclassoopextending

Call parent method in JavaScript class but stll have access to prototype methods inside object instance?


Is it possible to call parent method in JavaScript class but to still have access to prototype methods from parent and child class. Here is code example:

var Base = function() {

  this.baseMethod = function(){
    return 'baseMethod';
  };

  this.baseInitMethod = function() {
    return 'baseInitMethod';
  }
}


Base.prototype.basePrototypeMethod = function() {
  return "basePrototypeMethod";
};


var Specific = function() {

  Base.call(this);

  this.baseInitMethod = function() {
    // call baseInitMethod from Base class
  }

  this.specificMethod = function(){
    return 'specificMethod';
  }

  this.specificInitMethod = function() {

    return this.basePrototypeMethod();
  }
}


Specific.prototype.specificPrototypeMethod = function() {
  return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
}


for(var p in Base.prototype) {
   Specific.prototype[p] = Base.prototype[p]
}


var s = new Specific();


console.log(s.baseMethod());

console.log(s.baseInitMethod());

console.log(s.basePrototypeMethod());

console.log(s.specificMethod());

console.log(s.specificInitMethod());

console.log(s.specificPrototypeMethod());

I want to call baseInitMethod in Base class from baseInitMethod method inside Specific class but so that all function calls from above still works. Is that possible?


Solution

  • Your Specific.prototype object should inherit from the Base.prototype object. Currently you're copying over all its properties to the object with this code:

    for(var p in Base.prototype) {
       Specific.prototype[p] = Base.prototype[p]
    }
    

    But you should actually use Object.create to establish a real prototype chain:

    Specific.prototype = Object.create(Base.prototype);
    
    Specific.prototype.specificPrototypeMethod = function() {
      return 'specificPrototypeMethod' + '-' + this.baseInitMethod();
    }
    

    I want to call baseInitMethod in Base class from baseInitMethod method inside Specific class

    Yes. In your Specific constructor, you first need get Base's baseInitMethod instance method, before you overwrite the property of the instance:

    function Specific() {
        Base.call(this);
    
        var parentInitMethod = this.baseInitMethod;
        this.baseInitMethod = function() {
            // call baseInitMethod from Base class:
            parentInitMethod.call(this /*, arguments…*/); 
        }
    
        …
    }
    

    so that all function calls from above still works.

    I'm not sure what you mean by that exactly. The specificPrototypeMethod will always call the baseInitMethod of the current instance, which would be Specific's overwritten one not the original that was defined in Base.