Understanding Prototypical Inheritance in JavaScript

Understanding Prototypical Inheritance in JavaScript

Dipesh Chaulagain
Dipesh Chaulagain

7. Prototypical Inheritance

Prototypical inheritance is a feature in JavaScript that allows objects to inherit properties and methods from other objects. This inheritance is achieved through the prototype chain, where objects can have a prototype object that serves as a template from which to inherit methods and properties. This is different from classical inheritance in languages like Java or C++, where classes inherit from other classes.

Basics of Prototypical Inheritance

  1. Prototype Chain:
    • Every JavaScript object has a prototype.
    • The prototype is also an object, and it has its own prototype, forming a chain.
    • The chain ends with Object.prototype, which has null as its prototype.
  2. Accessing Properties and Methods:
    • When a property or method is accessed on an object, JavaScript first looks for it on the object itself.
    • If not found, it looks on the object’s prototype, and continues up the prototype chain until it finds the property or reaches the end of the chain.

Creating Prototypal Inheritance

Using Object.create()

The Object.create() method creates a new object with the specified prototype object and properties.

let personPrototype = {
  greet: function () {
    console.log('Hello, ' + this.name);
  },
};

let john = Object.create(personPrototype);
john.name = 'John';
john.greet(); // Hello, John

In this example:

  • personPrototype is an object that has a greet method.
  • john is created with personPrototype as its prototype.
  • john can access greet from its prototype.

Constructor Functions

Before ES6, constructor functions were commonly used to achieve inheritance.

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function () {
  console.log('Hello, ' + this.name);
};

let jane = new Person('Jane');
jane.greet(); // Hello, Jane

In this example:

  • Person is a constructor function.
  • Person.prototype is used to add methods that should be available to all instances of Person.
  • jane is an instance of Person, and it can access the greet method from Person.prototype.

ES6 Classes

ES6 introduced class syntax, which is syntactic sugar over the existing prototype-based inheritance. Classes in ES6 make it easier and more intuitive to create and work with prototypes.

class Person {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log('Hello, ' + this.name);
  }
}

let john = new Person('John');
john.greet(); // Hello, John

In this example:

  • Person is a class with a constructor and a greet method.
  • john is an instance of Person and can access the greet method.

Inheritance with Prototypes

Prototypal inheritance allows objects to inherit from other objects. This can be done using Object.create() or class inheritance.

Using Object.create()

let animal = {
  speak: function () {
    console.log(this.sound);
  },
};

let dog = Object.create(animal);
dog.sound = 'Woof';
dog.speak(); // Woof

Using ES6 Classes

class Animal {
  constructor(sound) {
    this.sound = sound;
  }

  speak() {
    console.log(this.sound);
  }
}

class Dog extends Animal {
  constructor() {
    super('Woof');
  }
}

let dog = new Dog();
dog.speak(); // Woof

In this example:

  • Animal is a base class with a speak method.
  • Dog extends Animal, inheriting its properties and methods.
  • super is used to call the constructor of the base class.

Prototype Chain

The prototype chain can be visualized as a series of links between objects, where each object has a link to its prototype:

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function () {
  console.log('Hello, ' + this.name);
};

let john = new Person('John');

console.log(john.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true

Conclusion

Prototypical inheritance in JavaScript is a powerful feature that allows for flexible and efficient object-oriented programming. Understanding how prototypes and the prototype chain work is essential for mastering JavaScript and effectively utilizing its inheritance model. Whether using Object.create(), constructor functions, or ES6 classes, prototypal inheritance enables code reuse and the creation of complex object hierarchies.