Why isn't this allowed before super()
Constructor function will return 'this' by default. According to oops concept child class always inherit 'this' object from parent class by super() call. so if we try to use this in child class without super call it will throw an error. If we return anything except 'this' from child class then super() call is not necessary. I have explained by some simple examples.
example 1
class A {
constructor() {
this.a = 0;
}
}
class B extends A {
constructor() {
console.log(this);
}
}
const instanceA = new A();
console.log(instanceA) // A {a: 0}
const instanceB = new B();
console.log(instanceB) // Error: Must call super constructor in derived class before
accessing 'this' or returning from derived constructor
example 2
class A {
constructor() {
this.a = 0;
}
}
class B extends A {
constructor() {
return {b: 3}
}
}
const instanceA = new A();
console.log(instanceA) // A {a: 0}
const instanceB = new B();
console.log(instanceB) // Object {b: 3}
example 3
class A {
constructor() {
this.a = 0;
}
}
class B extends A {
constructor() {
super()
}
}
const instanceB = new B();
console.log(instanceB) // B {a: 0}
This is really complicated, unfortunately.
The short story: access of this
in a subclass before super()
call is not allowed, because in ES6 this
is being born in the base class, therefore super()
is needed to initialize it.
For more information, refer to 15.6.2 Allocating and initializing instances1. The author is one of the few people that explains this in detail.
Here is a relevant sample from the book1 above.
Under the hood, it roughly looks as follows.
// Base class: this is where the instance is allocated
function Person(name) {
// Performed before entering this constructor:
this = Object.create(new.target.prototype);
this.name = name;
}
···
function Employee(name, title) {
// Performed before entering this constructor:
this = uninitialized;
this = Reflect.construct(Person, [name], new.target); // (A)
// super(name);
this.title = title;
}
The constructor method is a special method for creating and initializing an object created with a class. There can only be one special method with the name "constructor" in a class. A SyntaxError will be thrown if the class contains more than one occurrence of a constructor method. A constructor can use the super keyword to call the constructor of a parent class.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
It means if you have class MyComponent extends React.Component
you always need super()
call in order to make this defined.
If you don't specify a constructor method, a default constructor is used.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor#Default_constructors
Constructor of superclass should be called before this
in order to finish configuration of this
before subclass started configuration of this
. Otherwise superclass constructor could get this
modified by subclass. Superclass should not know something about subclasses. That is why super()
call in constructor should be before access to this
.