Master JavaScript Prototypes & Inheritance
Tags: javascript, webdev, programming, software
Published: 2017-08-18 04:12:24

---
title: Master JavaScript Prototypes & Inheritance
published: true
description: 
tags: JavaScript, web development, programming, software, webdev
---
This article is taken from my course, [Step Up Your JS: A Comprehensive Guide to Intermediate JavaScript](https://www.educative.io/collection/5679346740101120/5707702298738688?authorName=Arnav%20Aggarwal).

## Inheritance

Inheritance refers to an object’s ability to access methods and other properties from another object. Objects can *inherit* things from other objects. Inheritance in JavaScript works through something called prototypes and this form of inheritance is often called *prototypal inheritance*.

In this article, we’ll cover a lot of seemingly unrelated topics and tie them together at the end. There’s also a TL;DR at the end for those who want the short version.

## Object, Array, and Function

JavaScript gives us access to three global functions: `Object`, `Array`, and `Function`. Yes, these are all functions.

    console.log(Object); // -> ƒ Object() { [native code] }
    console.log(Array); // -> ƒ Array() { [native code] }
    console.log(Function); // -> ƒ Function() { [native code] }

You don’t know it, but every time you create an object literal, the JavaScript engine is effectively calling `new Object()`. An object literal is an object created by writing `{}`, as in `var obj = {};`. So an object literal is an implicit call to `Object`.

Same goes for arrays and functions. We can think of an array as coming from the `Array` constructor and a function as coming from the `Function` constructor.

## Object Prototypes

### \_\_proto\_\_

All JavaScript objects have a prototype. Browsers implement prototypes through the `__proto__` property and this is how we’ll refer to it. This is often called the *dunder proto*, short for double underscore prototype. Don’t EVER reassign this property or use it directly. The [MDN page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto) for `__proto__` warns us in big red blocks to never do this.

### prototype

Functions also have a `prototype` property. This is distinct from their `__proto__` property. This makes discussion rather confusing, so I’ll spell out the syntax I’ll be using. When I refer to a prototype and the word “prototype isn’t highlighted grey, I’m referring to the `__proto__` property. When I use `prototype` in grey, I’m talking about a function’s `prototype` property.

If we were to log the `prototype` of an object in Chrome, this is what we’d see.

    var obj = {};
    console.log(obj.__proto__);
    // -> {constructor: ƒ, __defineGetter__: ƒ, …}

The `__proto__` property is a [reference](https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0) to another object that has several properties on it. Every object literal we create has this `__proto__` property pointing to this same object.

There are a couple of important points:

* The `__proto__` of an object literal is equal to Object.prototype

* The `__proto__` of Object.prototype is null

We’ll explain why soon.

## The Prototype Chain

To understand object prototypes, we need to discuss object lookup behavior. When we look for a property of an object, the JavaScript engine will first check the object itself for the existence of the property. If not found, it’ll go to the object’s prototype and check that object. If found, it’ll use that property.

If not found, it’ll go to the prototype’s prototype, and on and on until it finds an object with a `__proto__` property equal to `null`. So if we were to attempt to look up the property `someProperty` on our obj object from above, the engine would first check the object itself.

It wouldn’t find it and would then jump to its `__proto__` object which is equal to `Object.prototype`. It wouldn’t find it there either and upon seeing that the next `__proto__` is `null`, it would return `undefined`.

This is called the prototype chain. It’s normally described as a chain going downwards, with `null` at the very top and the object we’re using at the bottom.

When performing a lookup, the engine will traverse up the chain looking for the property and return the first one it finds, or `undefined `if it’s not present in the prototype chain.

    __proto__ === null
    |
    |
    __proto__ === Object.prototype
    |
    |
    { object literal }

This can be demonstrated. Here we’re going to work with `__proto__` directly for the purpose of demonstration. Again, don’t ever do it.

    var obj = {};
    obj.__proto__.testValue = 'Hello!';

    console.log(obj); // -> {}
    console.log(obj.testValue); // -> Hello!

This prototype chain is depicted below.

    __proto__ === null
    |
    |
    __proto__ === Object.prototype -> testValue: 'Hello!'
    |
    |
    obj

When we log `obj`, we get an empty object because the property `testValue` isn’t present directly on the object. However, logging `obj.testValue` triggers a lookup. The engine goes up the prototype chain and finds `testValue` present on the object’s prototype and we see that value printing out.

## hasOwnProperty

There’s a method available on objects called `hasOwnProperty`. It’ll return `true` or `false` based on whether the object itself contains the property being tested. Testing for `__proto__`, however, will ALWAYS return false.

    var obj = {};
    obj.__proto__.testValue = 'Hello!';

    console.log(obj.hasOwnProperty('testValue'));
    // -> false

    console.log(obj.__proto__.hasOwnProperty('testValue'));
    // -> true

## Function prototypes

As mentioned, functions all have a prototype property distinct from their `__proto__` property. It’s an object. **A function’s prototype's `__proto__` property is equal to `Object.prototype`**. In other words:

    function fn() {}
    console.log(fn.prototype.__proto__ === Object.prototype);
    // -> true

### Function Prototypes and 'new'

A function’s `prototype` property shows its usefulness in object oriented programming. When we [invoke a function using `new`](https://codeburst.io/javascripts-new-keyword-explained-as-simply-as-possible-fec0d87b2741), the object bound to this in the constructor function is special. The new keyword sets the object’s `__proto__` to be the prototype property of the constructing function.

**When we call a function with `new`, it sets the returned object’s `__proto__` property equal to the function’s `prototype` property.** This is the key to inheritance.

We’ve assembled a few points so far:

* The `__proto__` of an object created by calling a function with `new` is equal to the `prototype` of that function

* The `__proto__` of a function’s `prototype` is equal to `Object.prototype`

* The `__proto__` of `Object.prototype` is `null`

This lets us assemble the following prototype chain.

    function Fn() {}
    var obj = new Fn();

    console.log(obj.__proto__ === Fn.prototype);
    // -> true

    console.log(obj.__proto__.__proto__=== Object.prototype);
    // -> true

    console.log(obj.__proto__.__proto__.__proto__ === null);
    // -> true

Visually drawn:

    __proto__ === null
    |
    |             
    __proto__ === Object.prototype
    |
    |
    __proto__ === Fn.prototype
    |
    |
    obj

## Implementing Inheritance

We can work with a function’s `prototype` property directly and safely. By placing methods and other properties on a function’s `prototype`, we enable all objects created by that function (using `new`) to access those properties through inheritance.

    function Fn() {}

    Fn.prototype.print = function() {
        console.log("Calling Fn.prototype's print method");
    };

    var obj = new Fn();
    obj.print(); // -> Calling Fn.prototype's print method

You might be wondering what the point of this is. We can just attach this method inside the constructing function itself, like this.

    function Fn() {
        this.print = function() {
            console.log("Calling the object's print method");
        };
    }

    var obj = new Fn();
    obj.print(); // -> Calling the object's print method

You’re right, this works. The difference is that this way, each object created by calling `new Fn()` will have its *own version* of `print` placed directly on the object. They’ll be distinct functions in memory. The problem with this is performance and memory usage.

### Performance

There may be times when you need thousands of new objects created from a constructor function. Using this second way of attaching `print`, we now have thousands of copies of `print`, each one attached to one of the objects.

Using the prototype chain, no matter how many objects we create out of `Fn`, we have one `print` sitting on `Fn.prototype`.

One method is not a big deal. Large programs, however, often have tens of methods that objects need. If an object needs access to 20 methods and we create 100,000 objects, the JavaScript engine has created 2,000,000 new functions.

If this needs to happen multiple times, this will cause noticeable speed and memory issues. Compare this to having a total of 20 functions and giving each object the ability to use the same functions through the prototype chain. Much more scalable.

Using `console.time` and `console.timeEnd`, we can directly show the difference in how long it takes. Here’s the time difference of creating 2 million objects with functions directly on them vs. on the prototype. We’re storing all the objects in an array.

![](https://cdn-images-1.medium.com/max/2872/1*k0m7VzTBqP0TwQCVR-GwRQ.png)

![Creating new functions (left) vs. using prototypal inheritance (right)](https://cdn-images-1.medium.com/max/2552/1*v3j_bKs15FjzONFkID2ikg.png)*Creating new functions (left) vs. using prototypal inheritance (right)*

As we can see, putting the print method on the `prototype` takes about half the time.

## `__proto__` of Literals

As mentioned, an object’s `__proto__` is equal to the `prototype` of the function that created the object. This rule applies to literals also. Remember that object literals come from `Object`, arrays come from `Array`, and functions come from `Function`.

    var obj = {};
    var arr = [];
    function fn() {}

    console.log(obj.__proto__ === Object.prototype); // -> true
    console.log(arr.__proto__ === Array.prototype); // -> true
    console.log(fn.__proto__ === Function.prototype); // -> true

We can now explain why we’re able to call methods on arrays and objects. If we have an array `arr`, we can `call arr.map()` because the method `map` is present on `Array.prototyp`e. We can call `obj.hasOwnProperty()` because `hasOwnProperty` is present on `Object.prototype`. We’ve been using inheritance the whole time and didn’t even know it.

The end of the `__proto__` chain of both `Array` and `Function` is equal to `Object.prototype`. They all derive from the same thing. This is why arrays, functions, and objects are all considered first-class objects in JavaScript.

## constructor

We’ve thrown the word constructor around a few times. Let’s explain what it is. Every function’s `prototype` has a `constructor` property on it that points back to the function itself. This is something the engine does for every function.

    function Fn() {}
    console.log(Fn.prototype.constructor === Fn);
    // -> true

An object created by running `new Fn()` will have its `__proto__` equal to Fn.prototype. So if we were to attempt to log the constructor property of that object, the engine would give us `Fn` through its lookup process.

    function Fn() {}
    var obj = new Fn();
    console.log(obj.constructor); // -> ƒ Fn(){}

### Why it’s Useful

The `constructor` property on an object is useful because it can tell us how an object was created. Logging the `constructor` property directly on an object will tell us exactly which function created our object.

    function Fn() {};

    var normalObj = {};
    var fnObj = new Fn();

    console.log(normalObj.constructor);
    // -> ƒ Object() { [native code] }

    console.log(fnObj.constructor);
    // -> ƒ Fn() {}

## Object.create

There’s a way to set the prototype of an object manually. `Object.create`. This function will take in an object as a parameter. It’ll return a brand new object whose `__proto__` property is equal to the object that was passed in.

    var prototypeObj = {
        testValue: 'Hello!'
    };

    var obj = Object.create(prototypeObj);
    console.log(obj); // -> {}
    console.log(obj.__proto__ === prototypeObj); // -> true
    console.log(obj.testValue); // -> 'Hello!'

This gives us an easy way to extend the prototype chain. We can make objects inherit from any object we like, not just a function’s `prototype`.

If you’d like more information and examples, the [MDN page for Object.create](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) is a great resource.

### Phew.

That was a *lot*. I know. However, you now have a deep understanding of inheritance in JavaScript.

## Prototypes Summary

In short, inheritance in JavaScript is implemented through the prototype chain. Every normally created object, array, and function has a prototype chain of `__proto__` properties ending with `Object.prototype` at the top. This is why they’re all considered first-class objects in JavaScript.

Functions have a `prototype` property in addition to the `__proto__` property. When using a constructor function with `new`, it’s good practice to place methods on the function’s `prototype` instead of on the object itself. The returned object’s `__proto__` will be equal to the function’s `prototype` so it will inherit all methods on the function’s `prototype`. This prevents unnecessary memory usage and improves speed.

We can check if an object has its own property by using the `hasOwnProperty` method. We can manually set up inheritance by using `Object.create`.

### That’s It. If this was helpful, please hit the heart so this story reaches more people. Also feel free to check out my other work.

## My Work

### Online Course

I’ve created an [online course](https://www.educative.io/collection/5679346740101120/5707702298738688?authorName=Arnav%20Aggarwal) covering intermediate JavaScript topics such as scope, closures, OOP, this, new, apply/call/bind, asynchronous code, array and object manipulation, and ES2015+.
[Step Up Your JS: A Comprehensive Guide to Intermediate JavaScript](https://www.educative.io/collection/5679346740101120/5707702298738688?authorName=Arnav%20Aggarwal)

### Recent Articles
[Explaining Value vs. Reference in Javascript](https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0)
[React Ecosystem Setup — Step-By-Step Walkthrough](https://codeburst.io/react-ecosystem-setup-step-by-step-walkthrough-721ff45a7fc1)