Object-oriented programming in JavaScript #2. Inheritance.

Viktor Kukurba
5 min readOct 4, 2018

--

In the first article we were talking about Abstraction, so let’s consider the next and very important principle, especially for JavaScript.
Inheritance in JavaScript ES2018 has some specific differences behind the scene if compare to other OOP languages, but the syntax looks similar.
Inheritance is an approach of sharing common functionality within a collection of classes. It provides an ability to avoid code duplication in a class that needs the same data and functions which another class already has. At the same time, it allows us to override or extend functionality that should have a different behavior.

Class inheritance example

On this diagram, ClassB and ClassD inherit functionality from ClassA. It means that instances of those classes, for example ObjectB, will have the same list of properties and methods as ObjectA that is an instance of ClassA. And still, ObjectB has additional properties and methods that are described in ClassB.

ClassA is called a super class or a parent class of ClassB and ClassD, which are called child classes.

ClassC is a child of ClassB, and its instance has the same functionality as the instance of ClassB that includes also ClassA functionality.

Child classes have the same list of properties and methods but are able to override them.

Inheritance of ClassC, ClassB and ClassA calls multilevel. But inheritance of ClassB, ClassD from ClassA hierarchical.

The class keyword was introduced in ES2015, and it is the syntactic sugar, JavaScript remains prototype-based inheritance. Every object in JavaScript has an internal hidden property [[Prototype]].
Under the hood class is still a function. And each function has the public prototype property, which specifies an internal [[Prototype]] to be assigned to all instances of objects created by the given function when used as a constructor.

Let’s look into JavaScript prototype chain of objects displayed on the Diagram.

Prototype chain example

ObjectA was instantiated from ClassA. ObjectA internal property [[Prototype]] is a reference to the ClassA public property prototype that is an object itself with its own internal property [[Prototype]], which is the reference to the Object public prototype which internal property [[Prototype]] is referenced to null.

Almost all objects in JavaScript have Object.prototype on the top of their prototype chain.

As ObjectB is the instance of ClassB, its internal [[Prototype]] is referenced to the ClassB public prototype property which is an Object and its internal [[Prototype]] is referenced to the ClassA public prototype property as ClassB extends ClassA, then prototype chain goes the same way as it is in ClassA.prototype.

Similarly, ObjectC has ClassC.prototype as internal [[Prototype]] and the next part of the chain is same as of ObjectB.
It looks confusing, and developers who don’t try to understand it always complain as it is a big weakness. But if you learn it and are able to widely use it you’ll understand that prototype inheritance model is more powerful than the classic model, as it is easy to build a classic model on a top of the prototype model.

Let’s consider abstract implementation of the prototype chain displayed on the Diagram.

In JavaScript keyword extends is used to inherit parent the class in class declaration class ClassB extends ClassA {.

Keyword super is used to execute parent constructor (super();) and access the implementation of parent methods (super.methodB();).

The Object.getPrototypeOf(obj) method returns the prototype (i.e. the value of the internal [[Prototype]] property) of the specified object.

Object.prototype.constructor is a reference to the Object constructor function that was used to create the instance object.

The instanceof operator checks if the prototype property of a constructor appears anywhere in the prototype chain of an object.

In code example we have basic implementation of 3 classes displayed on diagram.

ClassA adds a property propA to every new instance of it, inside the constructor. Simple method methodA is defined in the class.

ClassB extends ClassA and inside of the constructor we are adding one more property propBto ClassB instances. Anytime we are defining constructor of child class we have to call super function before updating this. Function super applies properties of parent class on this created in the child class, not the prototype. Keyword super gives the ability to reuses methods from the parent class. Even if method is overridden in child class, super still calls method implemented in parent class. Method methodA is overridden in ClassB, so this.methodA inside of the ClassB is the reference to a new implementation made in that class. But if we would use super.methodA inside of ClassB it would refer to the implementation made in ClassA, in spite of it being overridden.

ClassC extends ClassB, so its instance should have 3 properties, and its methodC should return cumulated value (CBNEW B).

In most popular browsers property __proto__ of the Object is implemented that is equivalent to the internal [[Prototype]], but it is non-standard and not recommended to use. Anyway, you can check it in the browser console, if you’re interested to investigate it.

If we trying to access some property by key on an object, JavaScript looks for its key on Object’s own properties. If it does not find it there, then it goes through the prototype chain. If it find it there it returns value, if not, returns undefined.

If we want to override the method inside the child class, it is just added to the child Class prototype, but the parent class method implementation still lives somewhere in the prototype chain, but it is not executed as JavaScript is able to find a method on the upper level.

If we want to override the method inside the child class, it is just added to child Class prototype. But parent class method implementation still lives somewhere (in Class.prototype we inheriting from) in prototype chain, but is not executed as JavaScript is able to find method on upper level (child class).

So, inheritance is the very important and fundamental principle in OOP for understanding. JavaScript has mechanism to support this principle with common syntax with other OOP languages, but differences under the hood, which are based on prototype chain. Don’t regret spending a little more time studying this topic, it will save you a lot of time in the future when you come across some unexpected behavior in your JavaScript code.
In the next article we are talking about Polymorphism.

--

--