“Super” and “Extends” In JavaScript ES6 - Understanding The Tough Parts

Photo by Clément H on Unsplash

ES6 has made JavaScript look a lot simpler with the class syntax and its additional features. Today we are going to combine the class syntax feature with the concept of inheritance to get some code going. Yes, you guessed it right, we are going to take a look at the super and extends keywords in JavaScript’s ES6. The best way to learn a new feature is to dive right into it with an example. So, let’s do it!

super and extends In Action

If we want to extend a class in JavaScript, we can take the help of the keywords super and extends to do so. Let’s look at an example of how these keywords are used.

ES6 Class and Subclass Syntax

The above code has 2 JavaScript classes namely Animal and Gorilla.

The Gorilla class is a subclass or child class of Animal and it uses the extends keyword to set itself as a subclass.

However, the super keyword has been used in two different ways.
Did you guys notice the same? In Gorilla’s constructor (line 23 of code) 
super is used as a “function”. Whereas, Gorilla’s showVigour() (line 35) and dailyRoutine()(line 39) methods have used super as an “object”.

The super keyword is used in two ways because of the following reasons:
In line 23, the super keyword is used as a “function” which calls the parent class Animal with the parameters passed to Gorilla. This is a key step to be carried out in order to make sure that Gorilla is an instance of Animal.
In line numbers 35 and 39, super is used as an “object” which refers to an Animal instance (parent class). The super keyword here is used to call the methods of the parent class Animal explicitly.

People familiar with languages like C#, Java, Python can pretty much relate to how all this works. However, JavaScript was not so simple before ES6 came in, especially for classes. So how did people code without using class syntax, super and extends keywords? Or they never used such concepts before and suddenly decided to add them? Let’s find out!

Traditional JavaScript Classes

Truth is, object-oriented JavaScript did exist and used prototypal inheritance to extend classes. Let’s look at the exact same example but with traditional JavaScript syntax. Perhaps this will help us to find the hidden truth.

Object-Oriented JavaScript Before ES6

After looking at the code you guys must be thinking, wait a sec, where is the word class? Where is the constructor? How is it even possible to use inheritance in old JavaScript code without extends and super keywords? Doesn’t this code look ugly?

Yes I know how you guys feel, we are on the same page. Unfortunately, JavaScript’s underlying functionalities never changed. They always remained the same no matter what features got added to the language. The use of new keywords like class, constructor, super, extends just add syntactic flavor to code so as to make it readable and developer friendly.

Let me explain which lines of code from the ES6 example conform to the traditional JavaScript example.

If you guys are new to the concepts of prototype and inheritance in JavaScript, check out the following articles before going to the comparison section:

Both these references will help you to understand the next section really well.

Comparison Between ES6 And Traditional JavaScript Code

The following sections break down and compare the code written in ES6 and traditional JavaScript styles.

Class Declaration

The class declarations are compared in the following code snippet.

Class Declaration Comparison

Class declaration in ES6 directly uses class keyword followed by defining of instance variables inside the constructor. In traditional JavaScript, there is no such thing as class. In fact, a class is actually a function under the hood in JavaScript (Refer to line 11 of this snippet).

The constructor function at line 3 is exactly same as line 14. 
function Animal is actually the constructor function here.

Methods As Part Of The Class

Method Declaration Comparison

The lines of code spanning from 4 to 14 are the methods which exist on Animal class for ES6 style. However, traditionally this was not possible as there was no such thing as class where the methods could be declared so easily. In traditional JavaScript, adding methods to the prototype make the methods available to the class. Lines 19 to 29 are the methods for traditional JavaScript classes.

Mapping extends To Traditional JavaScript

The bigger difference comes when we try to extend the parent class with a subclass. Refer to the following code snippet:

Mapping extends keyword to traditional approach

We can see that the extends keyword takes care of extending the parent class Animal to the subclass in ES6 way, but the super keyword is also used here to make sure that Animal class is called via Gorilla’s constructor so as to inherit the characteristics and behaviors of the Animal. Here, the super keyword is used as a function to call Animal class for initializing Gorilla. Here, super is equivalent to Animal.call(this, …).

To make the same thing happen traditionally, a few additional steps are required. A function for the subclass Gorilla needs to be created as per line 10. Since the Gorilla is going to inherit the characteristics and behaviors of Animal it is a must to call the Animal’s constructor function inside Gorilla’s constructor as shown in line 11, this line is comparable to line 4 and does the same exact thing. Only we need to pass “this” reference explicitly to the Animal class to ensure the call was made from Gorilla class.

Furthermore, we need to set the Gorilla function’s prototype as a new object created from the Animal’s prototype as shown on line 11. In doing this, we are overriding Gorilla’s prototype object. Hence, on the following line 15, we need to set the constructor of Gorilla explicitly. These steps take care of setting the Gorilla class as a subclass of Animal class.

Mapping super To Traditional JavaScript

We already saw one mapping of super keyword i.e., line 4 and 19 in the following snippet where super is used as a function.

Mapping super keyword to traditional approach

The keyword super can also be used as an instance of the parent class as per lines 8 and 12 to call Animal class specific details.

To achieve the same, in traditional style lines 26 and 30 show how it’s done.
The super instance is actually ParentClassName.prototype.methodName.call(this, …) .
Hence, a lot of code needs to be written to make sure the Parent class’ methods are called explicitly.

Conclusion

I’m pretty sure that you guys will start using ES6’s class and inheritance features right away without the blink of an eye as you now know the level of complexity the traditional way provides. Also, Chrome and Firefox support ES6 as of now, but in order to make all browsers support ES6 features, a babel transpiler will be required to convert all the ES6 code into ES5 code.

I have also written an article as shown below related to loading your web pages under 1 second. Attached performance metrics and various trade-offs related to it. You will also find my open sourced version of the starter template code. Enjoy!

Happy hacking! 😄