Open In App

JavaScript Inheritance

Last Updated : 19 Feb, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows one class or object to derive properties and behaviours from another. In JavaScript, inheritance is like a parent-child relationship, where objects, functions, or classes can inherit properties and methods from others, allowing code reusability and structuring.

What is inheritance in JavaScript?

Think of inheritance in JavaScript like a family. Just like kids inherit traits from their parents, objects in JavaScript can inherit properties and actions from other objects. This means we don’t have to write the same code over and over again.

JavaScript does this using prototypes, which connect objects in a chain, allowing them to share features effortlessly. This makes coding easier, cleaner, and more efficient—just like learning from those who came before us.

Common Types of Inheritance

1. prototype-based inheritance

In JavaScript, everything (functions, arrays, strings) is an object. The prototype stores shared properties and methods, allowing all instances of a type to access them.

JavaScript
function Animal(name) {
    this.name = name;
}
Animal.prototype.speak = function () {
    console.log(`${this.name} makes a sound.`);
};

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

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

// Adding a new method to Dog
Dog.prototype.bark = function () {
    console.log(`${this.name} barks: Woof!`);
};

// Creating an instance
const myDog = new Dog("Buddy");

myDog.speak(); 
myDog.bark();  

Output
Buddy makes a sound.
Buddy barks: Woof!
  • Dog inherits from Animal using Object.create(Animal.prototype).
  • Animal.call(this, name); ensures Dog gets the name property.
  • Methods are checked in Dog.prototype, then Animal.prototype, then Object.prototype.
  • Dog.prototype.bark() adds a new method while still inheriting speak().

To learn more about prototypes you can refer JavaScript Prototypes

2. ES6 Class-based Inheritance

This code demonstrates class inheritance in JavaScript, where a child class (two) extends a parent class (one). The child class inherits properties and methods from the parent class.

JavaScript
class one {
    constructor(name) {
        this.name = name
    }
    speaks() {
        return `my name is ${this.name}`
    }
}
class two extends one {
    constructor(name) {
        super(name)
    }
}
const o = new two('Pranjal')
console.log(o.speaks())

Output
my name is Pranjal
  • Class one has a constructor that sets the name property and a speaks() method that returns a string using this.name.
  • Class two extends one and calls super(name) in its constructor to inherit the name property from the parent class.
  • When an instance of two (o) is created with 'Pranjal', it passes 'Pranjal' to the parent class (one).
  • Calling o.speaks() returns "my name is Pranjal" because two inherits the speaks() method from one.

3. Mixins for Inheritance

This code demonstrates prototypal inheritance and object merging using Object.assign(), allowing a constructor function (Person) to inherit methods from multiple objects (one and two).

JavaScript
const one = {
    speak() {
        return `${this.name} walks`
    }
}
const two = {
    walks() {
        return `${this.name} walks`
    }
}
function Person(name) {
    this.name = name
}
Object.assign(Person.prototype, one, two)
const person1 = new Person('Pranjal')
console.log(person1.speak())
console.log(person1.walks())

Output
Pranjal walks
Pranjal walks
  • Objects one and two contain methods speak() and walks(), but they are separate objects.
  • Person function is a constructor that assigns a name property to new instances.
  • Object.assign(Person.prototype, one, two) merges methods from one and two into Person.prototype, so all instances of Person inherit these methods.
  • Creating person1 with 'Pranjal' allows calling person1.speak() and person1.walks(), both returning "Pranjal walks", since this.name refers to the assigned name.

4. Inheritance with Object.create()

Object.create() in JavaScript creates a new object that uses another object as its prototype, allowing it to inherit all its properties and methods.

JavaScript
let obj = {
    name: 'Pranjal',
    age: 21,
    prints() {
        return `my name is ${this.name}`
    }
}
let obj1 = Object.create(obj)
obj1.name = 'Hello'
console.log(obj1.age)
console.log(obj1.prints())

Output
21
my name is Hello
  • obj is an object with properties name, age, and a method prints() that returns a string using this.name.
  • obj1 is created using Object.create(obj), meaning it inherits obj's properties and methods.
  • obj1.name is set to 'Hello', but it still inherits age from obj since age is not directly defined in obj1.
  • Calling obj1.prints() uses the overridden name property ('Hello'), so it prints "my name is Hello", while obj1.age still gets 21 from obj.

5. Inheritance with object.setPrototypeOf()

This code demonstrates prototypal inheritance using Object.setPrototypeOf(), which sets one object (two) as the prototype of another (one). This allows one to access properties from two.

JavaScript
const one = {
    speak() {
        return `${this.name} speaks`
    }
}
const two = {
    name: 'Pranjal'
}
Object.setPrototypeOf(one, two)
console.log(one.speak())

Output
Pranjal speaks
  • Object one has a speak() method that uses this.name.
  • Object two has a name property set to 'Pranjal'.
  • Object.setPrototypeOf(one, two) makes two the prototype of one, so one can access name from two.
  • Calling one.speak() returns "Pranjal speaks" because this.name now refers to two.name.

6. Factory functions for inheritance

This code demonstrates factory functions in JavaScript, where a function (createPerson) returns new objects with shared properties and methods.

JavaScript
function createPerson(name) {
    return {
        name: name,
        greet() {
            return `Hello my name is ${this.name}`
        }
    }
}
const one = createPerson('Pranjal')
const two = createPerson('Pranav')
console.log(one.greet())
console.log(two.greet())

Output
Hello my name is Pranjal
Hello my name is Pranav
  • createPerson(name) is a function that returns an object with a name property and a greet() method.
  • Each call to createPerson creates a separate object with its own name value but the same method structure.
  • one and two are different objects, created using createPerson('Pranjal') and createPerson('Pranav'), each having its own name.
  • Calling greet() on one and two prints "Hello my name is Pranjal" and "Hello my name is Pranav", as this.name refers to each object's name.

Best Practices for JavaScript Inheritance

  • Prefer Composition Over Inheritance: Instead of using deep inheritance trees, consider using object composition or mixins for better flexibility.
  • Use Class Syntax: ES6 classes make inheritance more readable and easier to maintain.
  • Understand Prototypes: JavaScript’s prototype chain plays a key role in inheritance, so knowing how it works helps in debugging and optimization.
  • Use super() in Derived Classes: Always call super() in the constructor before accessing this when extending a class.
  • Keep Inheritance Simple: Avoid deep inheritance chains as they can make debugging and maintenance harder.

Advantages of inheritance in JavaScript

  • Code Reusability: Inheritance lets you reuse common methods and properties, reducing code duplication.
  • Simplified Maintenance: Changes to shared behavior in a parent are automatically reflected in child objects, easing maintenance.
  • Consistent Structure: Inheritance helps create a uniform object structure, making the codebase easier to understand and debug.
  • Memory Efficiency: Shared methods on prototypes mean that each instance doesn’t carry its own copy, saving memory.
  • Enhanced Extensibility: It’s easier to extend functionality and build complex systems by building on existing components.

Conclusion

JavaScript inheritance lets objects share properties and methods, making your code more organized and reusable. It helps reduce repetition and makes it easier to maintain and extend your code. Whether using prototypes, classes, or mixins, inheritance helps you build on existing functionality. Understanding how it works makes it easier to write cleaner, more efficient code.


Next Article

Similar Reads