super Keyword in JavaScript – What Is the super Keyword?
The super
keyword searches a parent class or object literal for a specified static or prototypal property.
For instance, consider the following snippet:
// Create a new class:class Name { constructor() { console.log("Oluwatobi is my Name"); }}
// Create a child class:class Bio extends Name { constructor() { // Use super to access the parent class's constructor: super(); }}
// Invoke the Bio constructor class:new Bio();
// The invocation above will return:// "Oluwatobi is my Name"// {}
The super()
function call in the snippet above tells the computer to find a constructor
in the parent class’s prototype chain.
You can use the super
keyword as a “function caller” or “property accessor”. Let’s discuss how.
How to Use the super
Keyword as a Function Caller
The super()
function caller finds and invokes the parent class’s constructor()
method.
In other words, super()
allows you to access a parent class’s constructor
from the constructor
of a derived class.
Syntax of the super
keyword as a function caller
super(argument1, …, argumentN);
Example: How to use the super()
function caller
// Create a new class:class Name { constructor(name) { this.name = name; }}
// Create a derived class:class Bio extends Name { constructor(firstName) { // Use super to access the parent class's constructor: super(firstName); }}
// Create a new object instance:const myBio = new Bio("Oluwatobi");
// Check myBio's current value:myBio;
// The invocation above will return:// { name: "Oluwatobi" }
The super()
function call in the snippet above tells the computer to find and invoke the parent class’s constructor()
.
In other words, the super()
function call searches for a constructor
in Name
’s prototype chain.
Note the following:
- Calling
super()
allows JavaScript to use the parent class’sconstructor
to initializethis
. So, asuper()
function call is similar to writingthis = new ParentClass()
. - JavaScript requires you to call
super()
before using the keywordthis
. Otherwise, the browser will throw aReferenceError
. In other words, a derived class’sconstructor
cannot access an uninitialized keywordthis
.
Example: What happens if you access this
before super
in a derived class’s constructor
?
// Create a new class:class Name { constructor(name) { this.name = name; }}
// Create a derived class:class Bio extends Name { constructor(firstName) { this.lastName = "Sofela"; // Using the keyword this before super will cause the browser to throw a ReferenceError: super(firstName); }}
// Create a new object instance:const myBio = new Bio("Oluwatobi");
The snippet above throws an Uncaught ReferenceError
because a derived class’s constructor
cannot access the keyword this
before the super()
function caller.
Example: What happens if you use only this
keyword in a derived class’s constructor
?
// Create a new class:class Name { createName() { return "Sofela"; }}
// Create a derived class:class Bio extends Name { constructor() { this.firstName = "Oluwatobi"; // Using the keyword this before super will cause the browser to throw a ReferenceError: }}
// Create a new object instance:const myBio = new Bio();
The snippet above throws an Uncaught ReferenceError
because a derived class’s constructor
cannot access the keyword this
before the super()
function caller.
Now that we know how to use the super
keyword as a function caller, we can discuss using it as a property accessor.
How to Use the super
Keyword as a Property Accessor
You can use the super
keyword as a property accessor in your JavaScript classes and object literals.
- Class Usage: The
super
keyword searches a class’s parent for a specified static or prototypal class field. In other words,super
allows you to access a parent class’s static or prototypal properties from a child class. - Object Literal Usage: The
super
keyword searches an object’s parent for a specified prototypal property. In other words,super
allows you to access a parent object’s prototypal properties from a child object.
Syntax of the super
keyword as a dot notation property accessor
super.parentClassOrObjectProperty;
Example: Use the super
keyword’s dot notation to access the parent class’s static field
// Create a new class:class Name { // Create a static class field: static myName = "Oluwatobi";}
// Create a derived class:class Bio extends Name { // Create a static property from the parent class's static class field: static firstName = super.myName;}
// Check firstName's current value:Bio.firstName;
// The invocation above will return: "Oluwatobi"
We used the super
keyword in the snippet above to access the parent class’s static class field.
Example: Use the super
keyword’s dot notation to access the parent class’s prototypal field
// Create a new class:class Time { // Create a prototypal method: hourNow() { return new Date().getHours(); }
// Create a second prototypal method: minutesNow() { return new Date().getMinutes(); }}
// Create a derived class:class Moment extends Time { // Create an instance property using the parent class's prototypal methods: currentMoment = `The time is ${super.hourNow()}:${super.minutesNow()}.`;}
// Create a new object instance:const momentNow = new Moment();
// Check momentNow's current value:console.log(momentNow);
We used the super
keyword in the snippet above to access the parent class’s prototypal class fields.
Example: Use the super
keyword’s dot notation to access a parent object’s prototypal property
// Create a new object:const website = { // Create a method: showName() { return "CodeSweetly"; },};
// Create another object:const company = { // Create a method: showCompany() { return super.showName(); },};
// Change company's dunder proto to the website object:Object.setPrototypeOf(company, website);
// Invoke the showCompany method:company.showCompany();
// The invocation above will return: "CodeSweetly"
We used the super
keyword in the snippet above to access the parent object’s showName()
method.
You can also use the super
keyword as a bracket notation property accessor to search a parent class or object literal for a specified static or prototypal property.
Syntax of the super
keyword as a bracket notation property accessor
super[expresssion];
Example: Use the super
keyword’s bracket notation to access a parent class’s static field
// Create a new class:class Name { // Create a static class field: static myName = "Oluwatobi";}
// Create a derived class:class Bio extends Name { // Create a static property from the parent class's static class field: static firstName = super["myName"];}
// Check firstName's current value:Bio.firstName;
// The invocation above will return: "Oluwatobi"
We used the super
keyword in the snippet above to access the parent class’s static class field.
Note: super
cannot access a parent class’s instance class field because JavaScript sets an instance property on the object instance, not the class itself or its prototype chain. (super
searches only for a parent’s static or prototypal properties.)
Example: Use the super
keyword to access the parent class’s instance field
// Create a new class:class Name { // Create an instance class field: myName = "Oluwatobi";}
// Create a derived class:class Bio extends Name { // Create an instance property from the parent class's instance class field: firstName = super.myName;}
// Create a new object instance:const myBio = new Bio();
// Check myBio's current value:myBio;
// The invocation above will return:// { myName: "Oluwatobi", firstName: undefined }
The firstName
property’s value is undefined
because super
could not find a prototypal myName
field on the parent class.
Note: The keywords super
and this
allow you to search for a specified property in an object’s prototype chain. But they work in different ways. Let’s discuss their differences now.
super
vs. this
Keyword: What’s the Difference?
The difference between the super
and this
keyword is as follows:
super
searches for a specified prototypal property in a parent class’s prototype chain.this
searches for a specified prototypal property from a class’s object instance’s own properties to its prototype chain.
In other words, super
starts its search from the parent class’s prototype
property. But this
searches from an object instance’s local scope to its prototype chain.
For instance, consider the following code:
// Create a new class:class ParentClass { // Create a prototypal method: showId() { return "I am a parent."; }}
// Create a derived class:class ChildClass extends ParentClass { // Create a prototypal method: showId() { return "I am a child."; } // Create another prototypal method: getId() { console.log(super.showId()); console.log(this.showId()); }}
// Create a new object instance:const instanceObject = new ChildClass();
// Invoke the instanceObject's getId() method:instanceObject.getId();
// The invocation above will return:// "I am a parent."// "I am a child."
Here’s how super
and this
performed their searches:
super | this | |
---|---|---|
1. | Find | Find |
2. | (Suppose | Find |
3. | (Suppose | |
4. | (Suppose |
You can see that super
shortens the steps required to find a prototypal method.