Inheritance in JavaScript

🔗 What is Inheritance?

Inheritance in JavaScript is a mechanism that allows one object to access the properties and methods of another. It promotes code reuse and helps in organizing code into a hierarchy. JavaScript uses prototypal inheritance rather than classical (class-based) inheritance, though ES6 introduced class syntax that makes it look similar.

Note

🧠 JavaScript’s inheritance model is based on **prototypes**, not classes — but classes are syntactic sugar over prototypes.

👨‍👦 Prototypal Inheritance

Every JavaScript object has a hidden internal property called [[Prototype]] (accessible via __proto__ or Object.getPrototypeOf()) which points to another object. This chain is called the **prototype chain**.

Basic Prototypal Inheritance

const parent = {
  greet() {
    return "Hello from parent!";
  }
};

const child = Object.create(parent);

console.log(child.greet()); // "Hello from parent!"

Note

💡 If JavaScript doesn’t find a property/method in an object, it looks up its prototype chain.

🏗️ Constructor Function Inheritance

Before classes were introduced, constructor functions were used to simulate classical inheritance.

Constructor Function Inheritance

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

Animal.prototype.speak = function () {
  return `${this.name} makes a noise.`;
};

function Dog(name) {
  Animal.call(this, name); // Inherit properties
}

Dog.prototype = Object.create(Animal.prototype); // Inherit methods
Dog.prototype.constructor = Dog;

const dog = new Dog("Buddy");
console.log(dog.speak()); // "Buddy makes a noise."

🏷️ ES6 Class Inheritance

The class and extends keywords introduced in ES6 offer a more familiar syntax for inheritance.

Class-Based Inheritance

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

  speak() {
    return `${this.name} makes a noise.`;
  }
}

class Dog extends Animal {
  speak() {
    return `${this.name} barks.`;
  }
}

const dog = new Dog("Max");
console.log(dog.speak()); // "Max barks."

Note

🔥 Use super() to call the parent constructor and super.methodName() to access parent methods inside subclasses.

🧱 Inheritance Chain Example

Chained Inheritance

const grandparent = {
  say() {
    return "I am the grandparent.";
  }
};

const parent = Object.create(grandparent);
const child = Object.create(parent);

console.log(child.say()); // "I am the grandparent."

⚠️ Caveats & Best Practices

  • Avoid deep inheritance chains; prefer composition when possible.
  • Use Object.create for simple prototypal inheritance.
  • Use class/extends for readable, structured OOP-style inheritance.

📚 Learn More

>>"Don't fight the prototype — embrace it." 🧠