651.288.7000 info@intertech.com

Prototypal Inheritance in JavaScript: Understanding the Inheritance Chain

by | Sep 23, 2019

Prototypal Inheritance in javascript: Understanding the Inheritance Chain

JavaScript is unique in a lot of ways. It’s the major browser-supported language that powers most user interfaces online. It has its own quirks in syntax and equality that can range from endearing to maddeningly annoying. However, JavaScript’s biggest unique point is object inheritance and the prototype chain.

In nearly any interview for a front-end or JavaScript developer role, you’re likely to hear a question about prototypal inheritance, and for good reason. Inheritance is a critical concept in computer programming, and JavaScript inheritance works unlike any other programming language. Even experienced developers can get tripped up by the JavaScript prototype chain, its mechanics, and how it differs from other programming languages.

In this post, we’ll cover the essentials on prototypal inheritance in JavaScript.


Quick Recap: What Is Inheritance?

In most object-oriented programming languages, there is a mechanism for child objects to inherit methods and attributes from their parents. Popular languages like Java, C#, C++, and Python (among many others) all support this type of inheritance. Defining these objects and their inheritance structures is a matter of creating classes that extend one another. A class is a definition of attributes and behaviors, an object is an instance of a given class.

For instance, you might have a base Animal class with methods that allow animals to eat() and sleep(). Then, your Dog class inherits the eat() and sleep() methods from its Animal parent class while also defining its own methods like bark() and be_undyingly_loyal().

Inheritance is one of the core principles of object-oriented design. It helps build reusable and modular components of software applications because we can inherit from and extend the parent class in many different ways.


Inheritance in JavaScript

It’s possible to do object-oriented programming in JavaScript. Indeed, JavaScript has built-in support for inheritance between objects.

However, JavaScript is not a class-based language. While there is a class keyword in JavaScript since 2015, it’s only syntactic sugar. Under the hood, JavaScript has its own mechanism for defining and resolving inheritance relationships.

This mechanism is known as the prototype chain. There are two key things to know about the JavaScript prototype chain and how it differs from class-based languages. If you take nothing else from this article, these two points will get you pretty far in understanding JavaScript inheritance.

1. Prototypes are objects themselves

In class-based languages, the classes act as blueprints. No object of that class actually exists until you instantiate it in your program. So, you define the class, then you create an instance of that class.

In JavaScript, prototypes are objects themselves. In fact, every function in JavaScript has a __proto__ attribute and a special property called `prototype` that allows you to access the __proto__ attributes.

If you open your console in your browser (ctrl+shift+I in Chrome & Firefox), you can see this for yourself.

Let’s create a new function that does absolutely nothing. Just leave it empty:

function doSomething(){}

Then, let’s check out the default prototype property that JavaScript created for us:

console.log( doSomething.prototype );

You can see the constructor for the doSomething function is indeed doSomething(). However, every JavaScript function also inherits certain attributes and qualities from JavaScript’s default Object() prototype. So, you can see all those default methods as well.

    constructor: ƒ doSomething(),
    __proto__: {
        constructor: ƒ Object(),
        hasOwnProperty: ƒ hasOwnProperty(),
        isPrototypeOf: ƒ isPrototypeOf(),
        propertyIsEnumerable: ƒ propertyIsEnumerable(),
        toLocaleString: ƒ toLocaleString(),
        toString: ƒ toString(),
        valueOf: ƒ valueOf()

We can add data and methods to our doSomething prototype by setting them using .prototype:

doSomething.prototype.foo = "bar";

Then, if we look at the results of console.log( doSomething.prototype ); again we can see that new value:

    foo: "bar",
    constructor: ƒ doSomething(),
    __proto__: {
        constructor: ƒ Object(),
        ... // other default methods here

Cool! So we see doSomething is an object itself. We can define methods/data on doSomething’s prototype. We can also see the methods and data from doSomething’s parent prototype – Object().


2. JavaScript inheritance relationships are created/resolved on-the-fly at the time of interpretation

JavaScript is designed to run inside browsers, so it isn’t compiled and it needs to be simple to interpret and resolve at runtime.

The prototype chain keeps things simple by making everything a first-class object. Instead of class blueprints that can inherit once they’re instantiated as real objects, JavaScript just chains objects together to form inheritance relationships.

That might be a confusing sentence to read, and sometimes JavaScript’s chaining rules are confusing, so let’s look at an example:

let Animal = function (name) { // create an Animal base prototype
    this.name = name // set Animal attributes using the “this” keyword on Animal
Animal.prototype.eat = function () { // add Animal prototype methods
    console.log(`${this.name} is eating`) 
let Dog = function (name, breed) { // create a Dog sub-prototype
    Animal.call(this, name) // call the Animal object as a constructor
    this.breed = breed // set Dog attributes using the “this” keyword on Dog
Dog.prototype = Object.create(Animal.prototype) // give Dog access to Animal methods
Dog.prototype.bark = function () { console.log(‘Woof woof!’) } // add Dog-specific methods
Dog.prototype.constructor = Dog // reset constructor for new dogs to be Dog instead of Animal
fido = new Dog(‘Fido’, ‘Pointer’) // the “new” keyword just creates a copy of the Dog function & calls it
fido.name // “Fido” from Animal >> this.name
fido.breed // “Pointer” from Dog >> this.breed
fido.eat() // “Fido is eating” from Animal.prototype.eat
fido.bark() // “Woof woof!” from Dog.prototype.bark

Hopefully you can see how functions inherit from each other in this example. Ultimately, fido is just a copy of Dog, which in turn is a copy of Animal that’s called within the this-context of Dog.

If we look at fido’s prototype inheritance chain we can see these relationships:


  • Animal {bark: ƒ, constructor: ƒ}
    • bark: ƒ () <– Dog’s bark method
    • constructor: ƒ (name, breed) <– Dog’s arguments for setting breed attribute
      • arguments: null
      • caller: null
      • length: 2
      • name: “Dog”
      • prototype: Animal {bark: ƒ, constructor: ƒ}
      • __proto__: ƒ ()
      • [[Scopes]]: Scopes[2]
    • __proto__:
      • eat: ƒ () <– Animal’s eat method
      • constructor: ƒ (name) <– Animal argument for setting name attribute
      • __proto__: Object

When JavaScript finds that fido itself doesn’t have an eat method, it checks fido’s parent, Dog.prototype, methods. When Dog.prototype also doesn’t have an eat method, it checks Dog’s parent, Animal.prototype, where it finds the eat method.


Using the class Keyword

Since ECMA 2016, JavaScript has included a “class” keyword so that developers don’t have to bother with Object.create(), Instance.prototype.constructor, and ParentInstance.call().

When you use the class keyword, what’s really happening is what we see above. However, the class keyword makes it much easier to write. Now you can say:

class Animal {
    constructor(name) {
        this.name = name
    eat() {
        console.log(`${this.name} is eating`)
class Dog extends Animal {
    constructor(name, breed) {
        super(name) // initialize the parent class
        this.breed = breed
    bark() {
        console.log(‘Woof woof’)

And that’s it! The class keyword makes inheritance much easier.


Prototypal Inheritance in JavaScript

For JavaScript developers, it’s critical to know what your language is doing behind the scenes when you’re inheriting attributes and methods from one object to another. For developers who are familiar with other languages and new to JavaScript, understanding the prototype chain is going to be essential to getting stuff done.


About Intertech

Founded in 1991, Intertech delivers software development consulting and IT training to Fortune 500, Government and Leading Technology institutions. Learn more about us. Whether you are a developer interested in working for a company that invests in its employees or a company looking to partner with a team of technology leaders who provide solutions, mentor staff and add true business value, we’d like to meet you.