Search code examples
javascriptecmascript-6superecma

If i can call the parent methods via this then why to use the super in ES6?


Lets say we have a class ABC:

class ABC{
    constructor(param1, param2){
        this.prop1 = param1;
        this.prop2 = param2;
    }
    ABCMethod1(){
        console.log(this.prop1 + ' ' + this.prop2);
    }
}

And one another class XYZ that extends the class ABC:

class XYZ extends ABC{
    XYZMethod1(){
        this.ABCMethod1();
    }
}

So, ES6 introduced a new keyword super that is used to access the parent class members in the child class. But i can access the parent class members in the child class very easily by using the this:

var myObject = new XYZ('Property 1','Property 2');
myObject.XYZMethod1();

Which prints the following in the browser console:

Property 1 Property 2

Now lets do the same thing by using the super instead of this in the child class XYZ:

class XYZ extends ABC{
    XYZMethod1(){
        super.ABCMethod1();
    }
}

Now lets call the XYZmethod1() again to see what will be the result:

var myObject = new XYZ('Property 1','Property 2');
myObject.XYZMethod1();

Which prints the following in the browser console:

Property 1 Property 2

Result: Both this and super returns the same output Property 1 Property 2 in the console. So, if we can access the parent methods using the this then what is the purpose of super in the ES6, why should we use it? Can anyone tell in easy words with example?


Solution

  • If you have the same method defined in the parent and the child class, super explicitly allows you to get the parent's implementation. Yes, Javascript (and virtually all other OOP languages) will traverse the prototype chain upwards to find properties defined on parents, so you don't need it to call a parent's method. In fact, you don't necessarily know how many layers up a method is defined, so it would be madness to need it. You only need it to disambiguate when there's more than one possible implementation (the current class or its parent).

    This is mostly used when overriding the parent's implementation, but still wanting to call the parent's implementation:

    class Foo {
        constructor() {}
        bar() {}
    }
    
    class Baz {
        constructor() {
            super();
            console.log(42);
        }
    
        bar() {
            super.bar();
            console.log(42);
        }
    }