JavaScript Inheritance: Prototypal vs Classical Inheritance

Inheritance is a powerful feature of object-oriented programming that allows you to create new objects based on existing ones. Inheritance allows new objects (children) to acquire properties and behaviors of existing objects (parents). This promotes code reusability, maintainability, and organization.

In JavaScript, inheritance is implemented using objects and prototypes. Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.

Classical Inheritance vs Prototypal Inheritance

In classical inheritance, methods from a base class get copied into a derived class. In JavaScript, inheritance is supported by using the prototype object. Some people call it "Prototypal Inheritance" and some people call it "Behaviour Delegation". Here are some differences between classical and prototypal inheritance:

Classical Inheritance

  • Uses classes to create objects.
  • Classes define the properties and methods of an object.
  • Objects are created from classes.
  • Inheritance is achieved through the class hierarchy.

Prototypal Inheritance

  • Uses prototypes to create objects.
  • Objects inherit properties and methods from their prototypes.
  • Objects are created from other objects.
  • Inheritance is achieved through the prototype chain.

Implementing Inheritance in JavaScript

In JavaScript, you can implement inheritance using the Object.create() method. This method creates a new object with the specified prototype object and properties. Here's an example:

Javascript
                        
// Define a parent object
var parent = {
  name: "Parent",
  sayHello: function() {
    console.log("Hello, I'm " + this.name);
  }
};

// Define a child object
var child = Object.create(parent);
child.name = "Child";

// Call the sayHello method on the child object
child.sayHello(); // Output: "Hello, I'm Child"

In this example, we define a parent object with a name property and a sayHello method. We then create a child object using the Object.create() method and set its name property to "Child". Finally, we call the sayHello method on the child object, which outputs "Hello, I'm Child".

You can also use the prototype property to implement inheritance. Here's an example:

Javascript
                        
// Define a parent constructor function
function Parent(name) {
  this.name = name;
}

// Define a method on the parent's prototype
Parent.prototype.sayHello = function() {
  console.log("Hello, I'm " + this.name);
};

// Define a child constructor function
function Child(name) {
  Parent.call(this, name);
}

// Inherit from the parent's prototype
Child.prototype = Object.create(Parent.prototype);

// Set the constructor property
Child.prototype.constructor = Child;

// Define a method on the child's prototype
Child.prototype.sayGoodbye = function() {
  console.log("Goodbye, " + this.name);
};

// Create a child object
var child = new Child("Child");

// Call the sayHello and sayGoodbye methods on the child object
child.sayHello(); // Output: "Hello, I'm Child"
child.sayGoodbye(); // Output: "Goodbye, Child"

In this example, we define a parent constructor function with a name parameter and a sayHello method on its prototype. We then define a child constructor function that calls the parent constructor function and sets its prototype to an instance of the parent's prototype. We also define a sayGoodbye method on the child's prototype. Finally, we create a child object and call the sayHello and sayGoodbye methods on it.

Conclusion

Inheritance is a powerful feature of object-oriented programming that allows you to create new objects based on existing ones. In JavaScript, inheritance is implemented using objects and prototypes. You can implement inheritance in JavaScript using the Object.create() method or the prototype property. Understanding how prototypes work under the hood is still useful, even though classes are now widely adopted and have become a new paradigm in JavaScript ¹³.