Understanding and Using Prototypal Inheritance in JavaScript
Tags: javascript, inheritance, beginners
Published: 2020-04-09 17:49:06

*Written by Ryan Thelin, a contract technical writer for Educative.inc* 

JavaScript is a prototype-based, Object Oriented programming language. After the ES6 updates, JavaScript allowed for “prototypal inheritance”, meaning that objects and methods can be shared, extended, and copied. This makes for easy inheritance of structure (data fields), behavior (functions / methods), and state (data values). 

JavaScript is the most common of the prototype-capable languages, and its capabilities are relatively unique. When used appropriately, prototypical inheritance in JavaScript is a powerful tool that can save hours of coding.

Today, we want to get you acquainted with prototypal inheritance in JavaScript to get you up to date with the ES6 capabilities. 

We will cover the following:  
* [What is prototypical inheritance?](#what-is)
* [Cons of prototypical inheritance](#cons)
* [Important terms](#terms)
* [Setting up prototypical relationships](#relationships) 
* [Inheriting methods](#methods)
* [Three-Tier Inheritance and Scalability](#three-tier)
* [Wrapping up and resources](#resources)

<br>

## What is prototypical inheritance? <a name="what-is"></a>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/e5xu7m3pjfdzcgwndjc4.png)

Simply put, prototypical inheritance refers to the ability to access object properties from another object. We use a **JavaScript prototype** to add new properties and methods to an existing object constructor.  We can then essentially tell our JS code to inherit properties from a prototype. Prototypical inheritance allows us to reuse the properties or methods from one JavaScript object to another through a reference pointer function. 

All JavaScript objects inherit properties and methods from a prototype:

* `Date` objects inherit from `Date.prototype`.
* `Array` objects inherit from `Array.prototype`.
* `Player` objects inherit from `Player.prototype`.

The `Object.prototype` is on top of the prototype inheritance chain. ​ `Date` objects, `Array` objects, and `Player` objects all inherit from `Object.prototype`.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/j3h8td0ncyb3rcaio1zt.png)

*Image from [dsinecos](https://dsinecos.github.io/blog/What-is-prototypal-inheritance)*

### Revisiting an old example
 
Let’s walk through an example of prototypical inheritance you’re likely familiar with from grade school: all squares are rectangles, but not all rectangles are squares. If we think of this as a JS program, we could say that the rectangle is a prototype to the square: the square inherits all properties of a rectangle (i.e. four-sides and closed), while also adding a new feature (i.e. all sides are the same length). 

We could not, however, construct this same concept using the square as a prototype, because there are properties of a square that do not apply to rectangles (i.e. all sides are the same length). 


We can see how prototypal inheritance works on the basis of specifying categories within a group from least specific to most – from rectangle to square. In code, this concept can sometimes be lost in the syntax. If you find this happens, **speak the relations** between objects and listen to where you draw distinctions. If you hear, "all ___ are ___, but...not all ___ are___", that is where a new prototypical relationship should be added.

## Cons of Prototypal Inheritance<a name="cons"></a>

Prototypical inheritance clearly has a lot of benefits for JavaScript programmings, but, like all tools, it does have limitations. Let’s take a look at the key downsides to look out for as you write a prototype-based program:

* **Inheritance cannot flow in circles as this will create an error.** For example, if `user` linked `premiumFamily` as a prototype in the above program, an error would occur as this would create a loop.

* **Objects cannot inherit from multiple prototypes.** As we saw above, they can inherit multiple object's properties through a chain, however another object linked as a prototype explicitly will cause an error. This is the case even if the additional prototype is within the same chain. For example, `familyPremium` could not have explicit links to both `premiumUser` and `user`.

* **Prototypical relationships can only be made to objects.** This is because the `__proto__` function works as a forwarder, directing the program where to find the value it is looking for. As the program either knows where to look or it doesn’t, the function can be only either `null` or an object. All other types will be discarded.

<br>

## Important terms<a name="terms"></a>
 
### `__proto__` property 
In Javascript, every object has its own hidden, internal property, `[[Prototype]]`. We can access that `[[Prototype]]` using the `__proto__` property. This calls the program to mark the template object as a hidden type. JavaScript objects must be linked to this prototype object. Now, an object's properties can be accessed by the inheritor object. 

Let’s take a look at the syntax for accessing and setting the `[[Prototype]]` property of an object.


```js
//using __proto__ to access and set the [[Prototype]] of "anObject"
anObject.__proto__ = someotherObject
```

<br>

### Object.create
JavaScript ECMAScript 5 comes with the function `Object.create( )`. This method can be used to replace`new`. We can use it to create an empty object based on a defined prototype and then assign it to a different prototype. Take a look at the syntax:


```js
Object.create(proto, [propertiesObject])
```


`Object.create` methods can accept two arguments: `propertiesObject` and `prototypeObject`. 

<br>


### Object.prototype.constructor
All objects have a constructor property. If an object is created without the using a constructor function, it will have a constructor property. The constructor property will return a reference to the object’s `Object` constructor function. It will return `1`, `true1, and `”test”`. Take a look at an example below. 


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/s8zni91r48s7a37kq2bz.png)

<br>

### hasOwnProperty
Using `hasOwnProperty`, we can test if an object contains a certain prototype property; the method will return `true` or `false` depending. This will help you clarify if an object has its own property or if it is inheriting instead. Take a look at the syntax below:


```js
obj.hasOwnProperty(prop)
```

<br>

### The Prototype Chain 

Prototypal inheritance uses the concept of **prototype chaining**. Let’s explore that concept. Every object created contains `[[Prototype]]`, which points either to another object or null.  Envision an object C with a `[[Prototype]]` property that points to object B. Object B’s `[[Prototype]`] property points to prototype object A. This continues onward, forming a kind of chain called the prototype chain.

This concept is used when searching our code. When we need to find a property in an object, it is first searched for in the object, and if not found, it is searched for on that object’s prototype, and so on. Thus, the entire prototype chain is traversed until the property is found or `null` is reached.

> *Want to learn more about Prototypal Chaining? Check out the course [Learn Object-Oriented Programming in JavaSrcript](https://www.educative.io/courses/learn-object-oriented-programming-in-javascript)*

In the following sections, we'll take a look at some implementations using the handling of accounts in a streaming service. 

<br>

## Example Code 1: Setting up Prototypical Relationships <a name="relationships"></a>

For this first example, we'll write a simple prototypical relationship between two objects, `user` and `premiumUser`, using the `._proto_` function. Each of these objects has their own properties which would be shared among all accounts at that tier: all `users` have access to stream shows, `showAccess = true`, and all `premiumUsers` have advertisements disabled, `ads = false`



![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lmdvs7w3hcun8zp06f2q.png)


The prototypical relationship here ensures that `premiumUser` inherits the `showAccess` property set from `user` without having to set it manually at the premium tier. To check that this has inherited properly, we add a line to have the console print the current value of `showAccess` for `premiumUser`. As it returns `true`, we can see that `premiumUser` has inherited this property from `user`.

## Example Code 2: Inheriting Methods <a name="methods"></a>

Prototypal Inheritance can be used not only to inherit properties from other objects but methods as well. In the example below, we build off our previous code and now add `email` and `IDnumber` properties to user, tracking account info for this user, as well as a setter method, `accountInfo` which when called will parse a passed string, setting `email` and `IDnumber` to the new passed values.


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/n109fqvdsoeum2lg5vku.png)

The key section of this example is the calling of the three methods at the bottom. Each of these methods are defined under the `user` object and therefore would usually be inaccessible by `premiumUser`. However, because `user` is the prototype of `premiumUser`, all methods and properties of `user` are shared with any inheritor objects. 

From the final two methods, we also see how the value of the properties shared are not stagnant but can be set to new values regardless of the properties' values in the prototype.

<br>

## Example Code 3: Three-Tier Inheritance and Scalability <a name="three-tier"></a>

As you might have noticed, the examples above allow for only one account in `user` and one account in `premiumUser`. To introduce much needed scalability, we pivot from using these objects as variables and instead use them as an equivalent to classes. Instead of changing properties' values, we create new objects for each account, setting the prototype for that new object based on the tier of the account.

In the example below, the object `me` will be my account. This object then calls the inherited setter method to set values for the `email` and `IDnumber` property exclusive to this account, and set its tier by making the newly added `familyPremium` object as its prototype. While this is an example using a single account object, this procedure could be scaled to assign the correct properties to any number of objects.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/32s2z91n7c0dpvv97q9e.png)



Even with three levels of inheritance, we can see that `me` has access to data throughout the chain, from the immediately inherited `multipleDevices` property to the inherited `accountInfo` method, defined at the top of its chain in `user`. Regardless of how many levels the inheritance chain has, all information from previous levels are retained and accessible.

Through the use of prototypical inheritance, we're able to create a program in which new accounts can be added and assigned established properties in only a few lines of code rather than having to set manually. It also allows for ease of adaptability of those properties. If we could change properties of all inheritor accounts by only changing the properties in the prototype. 

As a result, we get a program which is scalable, adaptable, and efficient in execution, all possible thanks to a prototype-based approach.

<br>

## Wrapping up and real-world example  <a name="resources"></a>

Like JavaScript itself, prototypical inheritance is an invaluable tool in the world of website development and server management. Specifically, prototypes and prototypical inheritance are commonly used in many web application frameworks, such as AngularJS, to allow sharing of common behavior and state among similar components. 

For example, AngularJS uses hierarchical `scopes` for inheriting data values for data binding to display on web pages. A `Site` scope object may define values for the `Title` and `IconImg` for a website, then individual `Page` scope objects may use prototype links to allow sharing of those common data values. It also allows customization for individual web pages by overriding or augmenting the inherited values for certain pages.

Regardless of what syntax is used, whether it’s a streaming service or web page design, prototypical inheritance is a useful tool for all web application development projects.

<br>

## Resources and further reading

### Articles 
* [Top 15 JavaScript Courses](https://www.educative.io/blog/15-javascript-courses-learn-web-dev-html-and-css): Interested in brushing up on JavaScript and prototypical inheritance skills? Take a look at this article to get started.


* [Complete Crash Course for ES6 and Beyond](https://www.educative.io/blog/javascript-es6-tutorial-a-complete-crash-course): Looking for an overview of ES6 JavaScript? This crash course article walks you through this modern JavaScript since ES6 and beyond.

* [The Journey to Becoming a Full Stack JS Developer Starts Here](https://www.educative.io/blog/the-journey-to-become-a-full-stack-js-developer-starts-here): Just starting out on your journey as a JavaScript developer? This article teaches aspiring developers all the need-to-know steps. 

### Essential Courses
* [JavaScript in Practice: Getting Started](https://www.educative.io/courses/javascript-in-practice-getting-started)
* [JavaScript in Practice: ES6 and Beyond](https://www.educative.io/courses/javascript-in-practice-es6-and-beyond)
* [The JavaScript Interview Handbook: 100+ Interview Questions](https://www.educative.io/courses/javascript-interview-handbook)
* [Learn Object-Oriented Programming in JavaScript](https://www.educative.io/courses/learn-object-oriented-programming-in-javascript)