Search code examples
javascriptinheritanceprototypal-inheritance

Proper way to call superclass functions from subclass


I have a "SuperClass" with "info" as an instance variable. "SuperClass" has function "printInfo()". "printInfo()" needs to access instance variable "info". I want to create a "SubClass" which also has method "printInfo()". I want to call printInfo() of "SuperClass" from "printInfo()" of "SubClass".

SuperClass = function()
{
    this.info = "I am superclass";
    console.log("SuperClass:");
};

SuperClass.prototype.printInfo = function(that)
{
    console.log("printing from superclass printInfo");
    console.log(that.info);
};

SubClass = function(){};

SubClass.prototype = new SuperClass();

SubClass.prototype.printInfo = function()
{
    console.log("calling superclass");
    this.constructor.prototype.printInfo(this);
    console.log("called superclass");
};

var sc = new SubClass();
sc.printInfo();

You can see that I am passing "that" as a parameter to printInfo. Without "that" parameter, "info" is printed as "undefined". Like in the following case, "this.info" is undefined when this function is called from object of "SubClass".

SuperClass.prototype.printInfo = function()
    {
        console.log("printing from superclass printInfo");
        console.log(this.info);
    };

What is the proper way to override and invoke methods of superclass in javascript, enabling functions to access instance variables of the class?


Solution

  • You are messing with the SubClass's prototype with the SuperClass's object, in this line

    SubClass.prototype = new SuperClass();
    

    the child's prototype should depend on the Parent's prototype. So, you can inherit like this

    SubClass.prototype = Object.create(SuperClass.prototype);
    

    Also, it is quite normal to change the constructor to the actual function, like this

    SubClass.prototype.constructor = SubClass;
    

    To keep your implementation generic, you can use Object.getPrototypeOf, to get the parent prototype in the inheritance chain and then invoke printInfo, like this

    SubClass.prototype.printInfo = function() {
        Object.getPrototypeOf(SubClass.prototype).printInfo(this);
    };
    

    Since, info is defined in the SubClass yet, it will print undefined. You might also want to call the parent't constructor, like this

    var SubClass = function() {
        SuperClass.call(this);
    };
    

    Note: You are creating global variables, by omitting var keyword before SuperClass and SubClass.