JavaScript Classes, Inheritance, and Prototype Chaining (ES5 and ES6 Way)
Understanding and implementing object-oriented programming
An article from https://knowledgescoops.com
A JavaScript Class (ES6)
One can relate a class in JavaScript to a class in an object-oriented programming language. A class might look something like:
As a programmer, we simply create instances of the class as:
var user = new User('Kunal');
console.log(user);
The class object gets logged as in the image above. See how an instance created for a class is represented internally with prototypes and the object’s key-value pairs.
Classes in ES5
Converting a class to ES5
The user instance we’ve just seen is represented by the prototypes and object’s key-value pairs which is the ES5 syntax. So, we can clearly say that classes are just syntactical sugar over ES5 code.
Consider the scenario if you had to write the same code in ES5, without any syntactical sugar. We can use an object creation pattern here.
The code we have written above can be written in ES5 using the following constructor function:
As you can see, we get a similar output in the console as we get when creating an instance from a class.
__proto__ Inside __proto__
Prototype chaining
Did you notice that we have a __proto__
inside the __proto__
?
That’s prototype chaining.
In JavaScript, every object has a prototype and we also know that the prototype of an object is also an object, thus creating nesting of prototypes.
So, JavaScript uses a similar concept for creating an inheritance by chaining multiple instances to prototypes and creating nested prototypes.
For example, the object shown in the above image is the User
object. We can assign the User.prototype.prototype
to be an instance of the Person
class. Thus creating an inheritance by chaining of the prototypes.
I will explain this in detail with the help of an example later in this article.
Objects Created With Classes (ES6) vs. Objects Created With Constructor Functions (ES5)
Are they exactly the same?
Although they seem to be the same, upon expanding the inner __proto__
, we get to see the difference between the two.
Upon expanding the __proto__
for the instance created with the class syntax, we get nothing in the inner __proto__
object.
On the other hand, expanding the inner __proto__
for the instance created with the constructor function gives the result as:
This means the instance created by the ES5 constructor function is inheriting from JavaScript’s object while the instance created with the class syntax is not inheriting any of the properties from JavaScript’s object class.
With classes, we get no inheritance by default and we get a pure object assigned to the inner __proto__
property of the User
object’s prototype.
We can also do that by explicitly modifying the inner __proto__
property.
Object.create(null)
creates a pure object for us.
Inheritance
The ES6 way — classes
Implementing a simple inheritance in ES6 would look like the example below.
This will log the user as:
On the outer prototype, we get the functions of User
(printUser
function) and on the inner prototype, we get the functions of Person
(printPerson
function).
We get the inheritance in action using prototype chaining, but with a syntactical sugar.
Inheritance — the ES5 way
While classes are just syntactical sugar over ES5, we must know how actually inheritance is implemented in ES5.
The above inheritance example using classes can be represented in ES5 using the following syntax:
In the above code, we majorly need to understand two things:
- The
__extends
function. Person.call(this)
.
The __extends
function takes two objects, the parent object, and the child object, and sets the prototype for the child.prototype
to the instance of the parent object.
Person.call(this)
calls the Person
function with custom this
context. Calling the Person
function with custom this
context includes the properties for the Person
object in the User
object.
Now, if we try to create the instance of the User
class, we will get:
var user = new User();
We get the same object as we received while creating an instance of the child class.
instanceof operator
For the instance created, there are properties of both User
and Person
. So the following two statements will return true
.
console.log(user instanceof User); // true
console.log(user instanceof Person); // true
More Articles to read …
For more such articles, visit www.knowledgescoops.com
Want to read more articles like this?
Follow me on medium @kunaltandon.ktConnect with me on LinkedIn:
https://www.linkedin.com/in/kunal-tandon/