The JavaScript Prototypal Inheritance Pattern

JavaScript is quite unique in the popular programming languages landscape because of its usage of prototypal inheritance.
While most object-oriented languages use a class-based inheritance model, JavaScript is based on the prototype inheritance model.

With that said, the Introduction to ECMAScript 2015 or popularly known as ES6 brought us classes, which is an emulation of how other programming languages dealt with the application of OOP concepts.

But primarily, this well-introduced use of classes in javascript, which made things a bit easier for newbies like myself and people coming from a well-structured class-based OOP language, doesn't change how javascript does its OOP which is known to be the prototype inheritance model.

The fact is, the class syntax introduced to ES6 is just but a syntactical sugar over JavaScript’s existing prototype-based inheritance, which means while these great tools, libraries, and all kinds of things that make your development easier, it's important to know the fundamentals and understanding of how things work under the hood, or as they call it the “weird parts” is what separates the average grunt coder from the senior developer in the JS ecosystem. Understanding this gives you a broader perception and changes the way you look at the development process.

What is prototype-based OOP?

Prototype-based programming is a style of object-oriented programming in which inheritance is implemented via the process of cloning existing objects that serve as prototypes. The question now becomes how do you create new objects with the same properties without classes for Inheritance?.

How It All Connects Together

Every object in JavaScript has an internal special hidden property called [[Prototype]] which points to a different object.

This different object is the object prototype.

Objects, as we know in JavaScript, uses this ability to inherit properties and methods directly from other objects through this shared property called [[Prototype]]and this [[Prototype]]is what is used for implementing inheritance in JavaScript objects.

Note: This inheritance is not the traditional inheritance that we’re used to in class-based languages, instead it’s something comparable to object delegation. By this I mean, if we attempt to access a property or method of an object, JavaScript will first search on the object itself, and if it is not found, it will search the object’s [[Prototype]]. If after consulting both the object and its [[Prototype]] still no match is found, JavaScript will check the prototype of the linked object, and continue searching until the end of the prototype chain is reached.

At the end of the prototype chain is Object.prototype. All objects inherit the properties and methods of Object. Any attempt to search beyond the end of the chain results in null.

Here is a quick snippet to show what I’m talking about:

Photo from Carbon.now.sh

To find the [[Prototype]] of this newly created object, we will use some of the inbuilt object methods.

Photo from Carbon.now.sh
Photo from Lucidchart.com
Our book object can use any property or method that Object has, even though its not a property of the object.book.toString();output => [object Object]

The same implies an array, number, function, or string in Javascript.

Photo from Carbon.now.sh
Photo from Lucidchart.com
We can perform this known methods and many more on arrays,
because they inherited this properties and methods through their [[Prototype]] linking to the Array.prototype which in turn links back to Object.prototype

Object.prototype is the base prototype of all the objects

The Concept Of Inheritance

With this found knowledge of prototype and how it works, One would ask, how do I actually make this inheritance thing work with POOP (Prototypal Object-Oriented Programming ) just like Class-based OOP languages do. With this, we first need to understand these keywords and what they do.

constructor, this, new and the Object.create keyword

What do these keywords do.?

A constructor or constructor function is a function that acts as a blueprint when we need to create objects of the same type, an example of this, is our new Array() and new Object(). The new keyword is used to create new instances based on the constructor function. While this keyword is a substitute for the new object on the constructor. The value of this will become the new object when a new object is created, and Object.create Creates a new object, with a specified prototype. For better understanding find the attached links useful

Implementing Inheritance

With this known power of the JavaScript Prototypal Inheritance. I figured building a simple Library Management System for an online Bookstore called Bookspy, would make us grasp how javascript OOP works.

Let's go by first building a book constructor/class, Which would be used to add all kinds of book objects to our book library.

Photo from Carbon.now.sh

Then let’s create our user constructor/class which would be used for creating users signing up to our platform for reading and buying any kind of book.

Photo from Carbon.now.sh

And lastly, let's make an Admin constructor/class, which would inherit from our User constructor/class above. As we all know, an admin is also a user but a special user with extra privileges.

Photo from Carbon.now.sh

A visual look at this behind the scenes with all User and Admin inherited methods would be.

From the given diagram, Our User constructor/class is used to construct instances of user with the new keyword, which is then made possible by the this keyword. and lastly, our Admin constructor/class prototype was pointed to User.prototype with the help of Object.create, which made inheritance of User properties and methods possible, this, in turn, made our code reusable without going to rewrite all needed methods for admin when our User class already has those methods. In trying to access any unknown method on an Admin like viewAllBooks(), Javascript will run a lookup down the admin object, since there is no method as such on the admin object, it would look the chain been the Admin prototype which also doesn't have viewAllBooks() method on it, so it goes further, looking through the chain again way to the User.prototype whence it is found, Javascript performs the necessary action needed for that operation called by the viewAllBooks() method.

If a method is accessed, and it’s not found in any of this given prototype from the single Book constructor/class or the User and its subclass Admin, Javascript will return an error telling us the property or method we tried to access is not found or it's not a function.

Photo from Carbon.now.sh

Conclusion

There are a lot of resources out there that explain how prototypal inheritance works in JavaScript. But so far with this learned, Class inheritance helps establish a hierarchy of objects. which in turn helps us write cleaner code and re-purpose the parent object to save memory on repeating object property and method definitions.

Classes are basically, the fundamental building blocks of application design and architecture. which most importantly helps in a large scalable and maintainable codebase. Of course, Bookspy was just an example. In a real-world scenario, it could be anything based on what type of application you’re trying to build. You can find the Bookspy repo here with all methods implemented and test with jest. Also, find the testing article useful if you looking to revisit or learn TDD

Bookspy repo and Bookspy TDD Article

Thanks for reading this post, I hope it helped you understand how to use prototypes in JavaScript.

Prototypal inheritance is a big topic. If you think I missed out on anything important then please respond and I will make sure to add it to this post.

Credits

Thanks to Flavio Copes, A teacher, blogger, and mentor, also the owner of flaviocopes.com for his bright insight on javascript OOP.

Get the Medium app