Skip to main content

Command Palette

Search for a command to run...

Prototypal Inheritance in JavaScript

Updated
4 min read

When I started learning JavaScript, one sentence kept popping up everywhere:

“JavaScript uses prototypal inheritance.”

At first, it sounded intimidating. But once I understood how property lookup actually works, everything became much clearer.

This blog explains prototypal inheritance from the ground up, using simple examples, and real intuition.


🧠 What Is Prototypal Inheritance?

Prototypal inheritance in JavaScript is a mechanism where objects inherit properties and methods from other objects.

Unlike classical languages (Java, C++), JavaScript does not copy properties from parent to child.
Instead, it delegates property access through a chain of objects.

This is why prototypal inheritance is better described as delegation, not traditional inheritance.


🔍 The Hidden [[Prototype]]

Every JavaScript object has a hidden internal property called:

[[Prototype]]

This property points to another object, known as the object’s prototype.

You can access it using:

Object.getPrototypeOf(obj);
// or (not recommended for production)
obj.__proto__;

🔗 How Property Lookup Works (Prototype Chain)

When you try to access a property:

obj.someProperty

JavaScript follows this process:

  1. Look for someProperty on obj

  2. ❌ If not found → look at obj.__proto__

  3. ❌ If still not found → look at obj.__proto__.__proto__

  4. Continue until:

    • Property is found ✅

    • Or prototype becomes null

This sequence is called the prototype chain.


📊 Prototype Chain Diagram

Once JavaScript reaches null, the search stops.


🏗️ Prototypal Inheritance Using Constructor Functions

Let’s look at a classic and very common example.

Parent Constructor

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

// Method added to prototype
Animal.prototype.makeSound = function () {
  console.log(`The ${this.constructor.name} makes a sound.`);
};

Child Constructor

function Dog(name) {
  Animal.call(this, name); // Call parent constructor
}

Setting Up the Prototype Chain

Object.setPrototypeOf(Dog.prototype, Animal.prototype);

Now Dog inherits from Animal.


Adding Child-Specific Method

Dog.prototype.bark = function () {
  console.log("Woof!");
};

Creating an Instance

const bolt = new Dog("Bolt");

console.log(bolt.name);    // Bolt
bolt.makeSound();          // The Dog makes a sound.
bolt.bark();               // Woof!

🔍 What’s Happening Internally?

When you call:

bolt.makeSound();

JavaScript does this:

  1. Look for makeSound on bolt

  2. ❌ Not found

  3. Look on Dog.prototype

  4. ❌ Not found

  5. Look on Animal.prototype

  6. ✅ Found → execute


🔁 Prototype Chain for This Example

bolt
  ↓
Dog.prototype
  ↓
Animal.prototype
  ↓
Object.prototype
  ↓
null

⚠️ Important Notes (Very Common Confusion)

.makeSound is NOT copied

The method exists only once on Animal.prototype.
All Dog instances share it.

This is memory efficient.


✔ Delegation, Not Classical Inheritance

JavaScript doesn’t duplicate methods like class-based languages.

Instead:

If an object doesn’t have a property, it delegates the lookup to its prototype.


❗ About Object.create() vs Object.setPrototypeOf()

  • Object.create(proto) is still valid and widely used

  • Object.setPrototypeOf() is more explicit but slower if overused

Both work - just understand what they do.


🧑‍💻 Another Simple Example (Person)

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 user1 = new Person("Swarup", 25);
user1.sayHello();

Again:

  • sayHello is not on user1

  • It lives on Person.prototype


🧩 Key Concepts Recap

🔹 Prototypes

Every object has a prototype (another object).

🔹 __proto__

Points to the object’s prototype (internal linkage).

🔹 prototype

A property on constructor functions used for inheritance.

user1.__proto__ === Person.prototype; // true

This line clears a lot of confusion.


🆕 What About ES6 Classes?

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

  greet() {
    console.log("Hello!");
  }
}

Even here:

  • Methods go to Person.prototype

  • Inheritance still uses the prototype chain

👉 Classes are just syntax sugar over prototypes.


🧠 Final Takeaway

JavaScript doesn’t copy properties—it looks them up through prototypes.

Once you understand this lookup process, topics like:

  • this

  • classes

  • inheritance

  • built-in methods

start making much more sense.


✨ Closing Thought

Prototypal inheritance feels confusing only when we try to force class-based thinking onto JavaScript.

When you think in terms of:

“If it’s not here, JavaScript will check somewhere else”

-everything clicks.