ES6 (2015) comes with new js features. One of them is the class keyword.
We know that javascript is a prototype-based language. That is to say all javascript objects inherit properties and methods from a prototype
object, for example Array
objects inherit from Array.prototype
its properties and methods like Array.prototype.length
and Array.prototype.push()
.Besides, Array.prototype
itself has a reference to Object.prototype
creating a prototype chain, in other words, Array
objects has access also to Object.prototype
methods and properties.And the same is valid for all other javascript objects.
This link between Object and prototype insured through --proto--
property created by default in every object and has a reference to the prototype.
NB : Object.prototype
is on the top of the prototype inheritance chain , its --proto--
has a reference to NULL
.
So, how prototype chaining works with es6 classes?
To answer this question, we have to understand how this magic word class
works really under the hood with a concrete example.
Class & constructor & new
We are going to create a class person with a constructor taking a name
and lastName
parameters besides a sayHello
method.
Declaring a class makes a lot of work under the hood thanks to Class
keyword.
- It creates a function as well as an object both called "Person", the Person function has a subtitle
constructor
that gets invoked when we instantiate the class.- It adds the
sayHello
method to the prototype property of the Person objectPerson.prototype
.
When class Person is instantiated with "Harry" and "Kane" arguments, they get assigned respectively to this.name
and this.lastName
.
But wait what is this
here?
When we instantiate a class with the new
keyword three things happen behind the scene :
- A new empty object gets created and assigned to
this
.--proto--
property ofthis
object get assigned toPerson.prototype
, namelythis.--proto-- = Person.prototype
.- It returns the object created.
Therefore , person
will hold an object with two properties: name
="Harry", lastName
="Kane" and person.--proto-- = Person.prototype
.
Extends & super
Now let's dive deep into this paradigm and create a new class Employee that "inherits" from Person class.
To do that we use the extends
keyword as demonstrates the example below.
When we instantiate Employee class the constructor gets invoked with the additional function super
.
super(name,lastName)
is equivalent to this= new Person(name,lastName)
, excepting, the object created will not be linked to Person.prototype
but to Employee.prototype
. In other words, this.--proto-- = Employee.prototype
.
Conclusion
From this example we conclude that Class feature is just a facade to object-oriented languages with a prototypal environment. It is syntactic sugar to prototype nature of javascript.
Top comments (5)
Just because JS uses prototypal inheritance rather than class based inheritance, doesn't mean it isn't object-oriented
But the manner of how object-oriented paradigm is achieved is different than the classical object-oriented programming language like java.
Note that Java way is not the only way. I think that the first OOP was in smalltalk that was completely different than Java. So you can't use that JS is not real OOP because it's not like Java. that way you can say that JS is not functional because it's not like Haskell, which make no sense at all. JavaScript is Object oriented even without ES6 classes, but use different approach then Java.
I was reading or watching video of Kyle Simpson (aka Getify) that classical classes are not exactly 1-1 map to prototypal inheritance, there is one or two cases where they work differently.
In this article I explained what really happens behind the scene with keywords "class" "extends" "super" "new".