Debunking the confusion around the ‘super()’ keyword in JavaScript(ES6 classes)

Dev sharma
3 min readSep 24, 2023

--

While surfing on the JavaScript forums lately, I saw a common query that many beginners were asking linked to the super() keyword associated with the Object-oriented paradigm in JavaScript (ES6 classes specifically). That is when I decided to write this article: to help fellow developers who are new to the language and clear their confusion.

SO WHAT IS THE TROUBLE?

1. “Is it a standard to call the super()keyword in the child class?”

2. “Is it possible to avoid super() constructor calls?”

These were some of the most frequently asked questions on the forums.

SO LET’S PUZZLE OUT THESE QUESTIONS.

Therefore, to tackle question no. 1, my answer will be:

YES!(one way or another) It is necessary to use the super() keyword in the child class according to the rules laid out for ES6:

Found this on MDN WEB DOCS

In the constructor body of a derived class (with extends), the super keyword may appear as a "function call" (super(...args)), which must be called before the this keyword is used, and before the constructor returns.

this cannot be used in the child class constructor until the super() is called.

"use strict";

class A {
constructor() {
console.log("hello");
}
}
class B extends A {
constructor() {
console.log("hi");
}
}

const foo = new B(); //ReferenceError: Must call super constructor in
// derived class before accessing 'this'

The reason you need to call super() in the child class is because JavaScript allocates instances in the base class first.

// Base class
class A {
// Allocate instance
constructor() {}
}
// Derived class
class B extends A {
constructor() {
// no `this` available, yet
super(); // receive instance from A
// can use `this` now
}
}

Now this brings us to question no. 2.

Now you can omit the constructor in the parent class and the derived class and exclude the super() in the child class, but…. even then, a default Constructor will be automatically included for you!

"use strict";


class A {
bar() {
console.log("hello");
}
}
class B extends A {}

const foo = new B();
foo.bar(); //hello will be printed out

The code above is equivalent to this:


class A {
constructor() {}
}

class B extends A {
constructor(...args) {
super(...args);
}
}

JavaScript will automatically include a default Constructor for you behind the scenes!

You can avoid the super constructor calls by either using the default constructors shown above or by explicitly returning an object from the derived class constructor.

// Base class
class A {
constructor() {}
}
// Derived class
class B extends A {
constructor() {
// No super-constructor call here!

return {}; // must be an object
}
}

const bar=new B();

But this can create problems of its own, as the newly created instance will not be able to inherit A’s methods.

But there is also a fix for that. We can use Object.create(new.target.prototype,...) to manually set up the prototype property, and we can easily inherit methods from a parent class.

example:

"use strict";

class Person {
calcAge() {
return 2023 - this.birthYear;
}
}

const Dev = Object.create(Person.prototype);
Dev.birthYear = 1995;
console.log(Dev.calcAge()); //28

I hope this information is useful.

--

--

Dev sharma
Dev sharma

Written by Dev sharma

An undergraduate student on his web dev journey! God bless you 🙌

No responses yet