Understanding JavaScript Prototypes: The Foundation of Inheritance in JavaScript

Understanding prototypes is essential for mastering JavaScript, as they form the backbone of inheritance and object-oriented programming in this language. In this article, we will delve into the concept of prototypes, how they work, and how we can use them to our advantage.

What is a Prototype?

Understanding JavaScript Prototypes: The Foundation of Inheritance in JavaScript

In JavaScript, every object has a hidden property called [[Prototype]] which is either null or references another object. This referenced object is known as the prototype. Prototypes are the mechanism by which JavaScript objects inherit properties and methods from one another.

Beside, I have created a user object, when we console that user object, we can see that the [[Prototype]], when we expand it we can see the properties present in the [[Prototype]] object, and it contain __proto__ object as well.

Prototypes in Action: Creating Objects

When you create an object using a constructor function, JavaScript sets up the prototype chain. Here’s an example to illustrate this:

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

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const john = new Person('John', 30);
john.sayHello(); // Output: Hello, my name is John and I am 30 years old.

In this example, the Person constructor function creates a new object with properties name and age. The sayHello method is defined on the Person.prototype object. Now, When we create a new Person instance, it can access the sayHello method through its prototype.

Prototype Chain

The prototype chain is the series of references between objects via the [[Prototype]] property. When you try to access a property or method on an object, JavaScript first looks for it on the object itself. If it doesn’t find it, it then looks at the object’s prototype, and so on up the chain until it finds the property or reaches the end of the chain (null).

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

Modifying Prototypes

You can add or modify properties and methods on an object’s prototype even after the object has been created:

Prototype vs __proto__

It’s important to distinguish between prototype and __proto__:

  • prototype is a property of constructor functions.
  • __proto__ (or [[Prototype]]) is a property of objects.
console.log(Person.prototype); // The prototype object of the Person constructor
console.log(john.__proto__); // The prototype object of the john instance

Inheriting Properties and Methods

Prototypes allow objects to inherit properties and methods from other objects. This is a fundamental aspect of JavaScript’s object-oriented programming capabilities.

Example: Creating a Subclass

Let’s create a subclass Student that inherits from Person:

function Student(name, age, grade) {
  Person.call(this, name, age);
  this.grade = grade;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

Student.prototype.study = function() {
  console.log(`${this.name} is studying.`);
};

const jane = new Student('Jane', 22, 'A');
jane.sayHello(); // Output: Hello, my name is Jane and I am 22 years old.
jane.study(); // Output: Jane is studying.

In this example, Student inherits from Person. We use Object.create to set up the prototype chain and ensure Student.prototype points to an object created from Person.prototype.