🧱 JavaScript Objects & OOP
Estimated reading: 6 minutes 13 views

🧠 JavaScript Inheritance and OOP Concepts: Prototypal Inheritance and ES6 Classes

In JavaScript, Object-Oriented Programming (OOP) is a programming paradigm based on the concept of “objects,” which can contain data (properties) and methods (functions). One of the core concepts in OOP is Inheritance, allowing objects to inherit properties and methods from other objects, promoting code reuse and logical hierarchy.

This guide covers the following key concepts related to inheritance in JavaScript and OOP:

  • What is Inheritance?
  • Prototypal Inheritance in JavaScript
  • Constructor Functions and Classes
  • Method Overriding and Extending Functionality
  • Best Practices and Usage

By the end of this guide, you’ll be equipped with a solid understanding of JavaScript inheritance and how to leverage OOP principles to write cleaner, more maintainable code.


📌 What Is Inheritance in JavaScript?

Inheritance is a mechanism where an object inherits properties and methods from another object. In classical OOP languages like Java or C++, inheritance works through class hierarchies. However, JavaScript uses prototypal inheritance, where objects can inherit directly from other objects.

💡 Key Facts:

  • Inheritance allows an object to access properties and methods from another object.
  • In JavaScript, inheritance is based on prototypes, where every object has a prototype property that points to another object.
  • This allows for shared behavior across multiple objects without the need for duplicating code.

📌 Prototypal Inheritance in JavaScript

JavaScript’s inheritance system is based on prototypes. Every JavaScript object has a prototype, which is another object from which it can inherit properties and methods. When a property or method is called on an object, JavaScript looks for it in the object itself. If not found, it checks the object’s prototype, and so on, up the chain.

📘 Example of Prototypal Inheritance:

// Constructor function for creating objects
function Animal(name) {
  this.name = name;
}

Animal.prototype.sayHello = function() {
  console.log(`${this.name} says hello!`);
};

// Create a new object with Animal as prototype
const dog = new Animal('Dog');

// Inherited method from Animal prototype
dog.sayHello();  // Output: Dog says hello!

✅ Line-by-Line Breakdown:

  1. function Animal(name) {...}: This defines a constructor function for creating instances of Animal objects.
  2. Animal.prototype.sayHello = function() {...}: Here, we define a method sayHello on the Animal prototype, so every instance of Animal can access this method.
  3. const dog = new Animal('Dog');: We create an instance of Animal called dog, passing "Dog" as the name.
  4. dog.sayHello();: This calls the sayHello method from the Animal prototype.

📌 Constructor Functions and Classes in JavaScript

Before the introduction of ES6 Classes, JavaScript used constructor functions to implement OOP principles. Constructor functions are special functions used to create and initialize objects.

In ES6, Classes provide a more familiar syntax for object creation and inheritance, making it easier to implement OOP.

📘 Example Using Constructor Function:

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

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

const person1 = new Person('Alice', 25);
person1.greet();  // Output: Hello, my name is Alice and I am 25 years old.

✅ Line-by-Line Breakdown:

  1. function Person(name, age) {...}: This is the constructor function that initializes the object with name and age properties.
  2. Person.prototype.greet = function() {...}: Adds a method greet to the Person prototype.
  3. const person1 = new Person('Alice', 25);: Creates a new instance person1 with name and age.
  4. person1.greet();: Calls the greet method, which is inherited from the prototype.

📘 Example Using ES6 Class Syntax:

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

  sayHello() {
    console.log(`${this.name} says hello!`);
  }
}

const cat = new Animal('Cat');
cat.sayHello();  // Output: Cat says hello!

✅ Line-by-Line Breakdown:

  1. class Animal { constructor(name) {...}: Defines a class Animal with a constructor that initializes the name property.
  2. sayHello() {...}: Defines the sayHello method directly inside the class.
  3. const cat = new Animal('Cat');: Creates an instance of Animal called cat.
  4. cat.sayHello();: Calls the sayHello method from the class prototype.

📌 Method Overriding and Extending Functionality

In JavaScript, we can override methods from a parent object or class, or extend functionality through subclassing.

💡 Overriding Methods:

Overriding allows a subclass to replace the method defined in its parent class with its own implementation.

class Animal {
  speak() {
    console.log("Animal makes a sound");
  }
}

class Dog extends Animal {
  speak() {
    console.log("Dog barks");
  }
}

const dog = new Dog();
dog.speak();  // Output: Dog barks

✅ Line-by-Line Breakdown:

  1. class Animal {...}: Defines a base class Animal with a speak method.
  2. class Dog extends Animal {...}: Creates a subclass Dog that inherits from Animal.
  3. speak() {...}: The speak method is overridden in the Dog class.
  4. const dog = new Dog();: Creates an instance of Dog.
  5. dog.speak();: Calls the overridden speak method of the Dog class.

📌 Best Practices for Using Inheritance

  • Favor Composition over Inheritance: Inheritance can sometimes lead to tightly coupled code. Using composition (i.e., combining simpler objects) can be a better solution in many cases.
  • Avoid Inheriting from Built-in Objects: Avoid inheriting from built-in JavaScript objects like Object, Array, or Date. This can lead to unexpected behavior.
  • Use class Syntax for Clarity: ES6 class syntax is more readable and easier to maintain than constructor functions and prototype chains.

📌 Summary

Inheritance is a powerful concept in JavaScript that allows you to extend functionality by creating objects that inherit properties and methods from other objects. Understanding prototypal inheritance, constructor functions, and ES6 classes is essential for writing clean and maintainable code.

  • Prototypal inheritance is at the core of JavaScript’s inheritance system.
  • Classes provide a more readable syntax for inheritance.
  • Method overriding and subclassing allow for extending or replacing functionality.
  • Following best practices can help avoid pitfalls associated with inheritance in JavaScript.

❓ FAQ

❓ What is the difference between classical inheritance and prototypal inheritance?

  • Classical inheritance involves classes that define the structure and behavior of objects, while prototypal inheritance in JavaScript allows objects to directly inherit from other objects. JavaScript does not have traditional classes in the classical OOP sense (until ES6), and it uses prototypes for inheritance.

❓ Can I use inheritance in JavaScript without using class?

  • Yes, you can use inheritance in JavaScript with constructor functions and the prototype chain. The class syntax introduced in ES6 is just syntactic sugar over this traditional method.

❓ How do I create a subclass in JavaScript?

  • You can create a subclass in JavaScript using the extends keyword. For example, class Dog extends Animal { ... } creates a Dog class that inherits from the Animal class.

Share Now :

Leave a Reply

Your email address will not be published. Required fields are marked *

Share

JavaScript — Inheritance / OOP Concepts

Or Copy Link

CONTENTS
Scroll to Top