JavaScript Prototypes: Understanding the Backbone of Object-Oriented JavaScript

ยท

3 min read

JavaScript is a powerful and flexible programming language that follows a prototype-based inheritance model. Unlike class-based languages like Java or Python, JavaScript uses prototypes to enable inheritance and object properties sharing.

Understanding prototypes is crucial for writing efficient and optimized JavaScript code, especially when dealing with objects and inheritance. In this blog, we will break down JavaScript prototypes step by step in an easy-to-understand manner.


1. What Are JavaScript Prototypes?

A prototype is an object from which other objects inherit properties and methods. Every JavaScript object has an internal link to another object called its prototype. This allows objects to share behavior without duplicating methods in memory.

Think of a prototype as a blueprint or a parent object that other objects can borrow properties and methods from.

Real-World Example ๐Ÿ“Œ

Imagine a company where employees share a common set of rules and benefits. Instead of rewriting these rules for every new employee, they simply inherit them from the company's guidelines. Similarly, JavaScript objects inherit from their prototypes.


2. The Prototype Chain ๐Ÿ”—

When an object tries to access a property or method, JavaScript first looks in the object itself. If it doesn't find the property, it walks up the prototype chain to look for it in the object's prototype, and so on, until it reaches the top (Object.prototype).

Example: Understanding Prototype Chain

const animal = {
  makeSound: function() {
    console.log("Some generic sound");
  }
};

const dog = Object.create(animal);
dog.bark = function() {
  console.log("Woof! Woof!");
};

dog.makeSound(); // Inherited from 'animal' prototype

How It Works:

  1. dog does not have a makeSound method.

  2. JavaScript checks dog's prototype (animal), which has makeSound, so it gets executed.


3. Creating Objects Using Prototypes

Method 1: Using Object.create()

This method creates a new object with a specified prototype.

const person = {
  greet: function() {
    console.log("Hello!");
  }
};

const student = Object.create(person);
student.study = function() {
  console.log("Studying JavaScript");
};

student.greet(); // Inherited from 'person'
student.study(); // Defined on 'student'

Method 2: Using Constructor Functions

A constructor function is a blueprint for creating multiple objects.

function Car(brand) {
  this.brand = brand;
}

Car.prototype.start = function() {
  console.log(`${this.brand} is starting...`);
};

const tesla = new Car("Tesla");
tesla.start();

What Happens Here?

  1. Car is a constructor function.

  2. Car.prototype.start adds a shared method for all car objects.

  3. tesla inherits start() from Car.prototype.


4. Prototype vs. __proto__ vs. prototype

Many beginners get confused between these terms. Let's clarify them:

__proto__ (Dunder Proto)

  • This is a reference to the prototype of an object.

  • Used to access the prototype chain.

  • Example:

      console.log(tesla.__proto__ === Car.prototype); // true
    

prototype Property

  • This exists only on functions.

  • It defines properties and methods that instances inherit.

  • Example:

      console.log(Car.prototype);
    

5. Modifying Prototypes: Good or Bad?

You can modify the prototype of built-in objects like Array.prototype or String.prototype, but it's usually a bad practice because it can lead to unexpected behavior.

Example: Adding a Custom Method to Arrays

Array.prototype.sayHello = function() {
  console.log("Hello from an array!");
};

const arr = [1, 2, 3];
arr.sayHello();

While this works, modifying built-in prototypes can cause conflicts with other libraries or future JavaScript updates.


6. Advantages of Prototypal Inheritance

โœ”๏ธ Reduces memory usage by sharing methods among instances.

โœ”๏ธ Encourages code reusability and modularity.

โœ”๏ธ Provides flexibility compared to classical inheritance in other languages.


JavaScript prototypes form the foundation of object-oriented programming in JavaScript. Understanding how the prototype chain works and how to use Object.create(), constructor functions, and prototype efficiently will make you a better JavaScript developer.