Sobes.tech
Junior

Explain how inheritance works in JavaScript.

sobes.tech AI

Answer from AI

Inheritance in JavaScript is implemented through prototypes. Each object in JavaScript has an internal property [[Prototype]], which references another object. When we try to access a property or method of an object that it doesn't have directly, the JavaScript engine searches for this property or method in the object's prototype. If it doesn't find it there, it continues the search up the prototype chain, which is formed by [[Prototype]] links, until it reaches null (the end of the chain).

There are two main inheritance mechanisms:

  1. Classical prototype inheritance (ES5 and earlier): Based on constructor functions and their prototype property.

    // Constructor function
    function Animal(name) {
      this.name = name;
    }
    
    // Add method to prototype
    Animal.prototype.speak = function() {
      console.log(`${this.name} makes a sound.`);
    };
    
    // Create an instance
    const dog = new Animal('Dog');
    
    // Call method from prototype
    dog.speak(); // Outputs: Dog makes a sound.
    
    // Prototype of dog is Animal.prototype
    console.log(Object.getPrototypeOf(dog) === Animal.prototype); // true
    
  2. Class inheritance (ES6 and later): Uses syntactic sugar class and extends, which under the hood still operate with prototypes.

    // Base class
    class Animal {
      constructor(name) {
        this.name = name;
      }
    
      speak() {
        console.log(`${this.name} makes a sound.`);
      }
    }
    
    // Subclass inheriting from Animal
    class Dog extends Animal {
      constructor(name, breeds) {
        super(name); // Call parent constructor
        this.breeds = breeds;
      }
    
      bark() {
        console.log(`${this.name} barks.`);
      }
    }
    
    // Create an instance of subclass
    const myDog = new Dog('Bublik', ['Labrador', 'Collie']);
    
    // Call methods from both Animal and Dog
    myDog.speak(); // Outputs: Bublik makes a sound.
    myDog.bark();  // Outputs: Bublik barks.
    
    // Prototype of myDog is Dog.prototype
    console.log(Object.getPrototypeOf(myDog) === Dog.prototype); // true
    
    // Prototype of Dog.prototype is Animal.prototype
    console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true
    

Key concepts:

  • Prototype chain: The connection between objects through their [[Prototype]].

  • __proto__ (deprecated/non-standard but useful for understanding): Property to access [[Prototype]]. Not recommended for production code.

  • Object.getPrototypeOf(obj): Standard way to get an object's prototype.

  • Object.setPrototypeOf(obj, proto): Standard way to change an object's prototype (not recommended to modify the prototype of existing objects after creation).

  • instanceof: Operator to check if an object is an instance of a class or constructor function by checking its prototype chain.

    console.log(myDog instanceof Dog);   // true
    console.log(myDog instanceof Animal); // true
    console.log(myDog instanceof Object); // true (at the end of the chain Object.prototype)
    
  • super: Used in classes to call methods or constructors of the parent class.

The difference between classical and class-based approaches: Classes provide a more structured and syntactically convenient way to work with prototype inheritance, similar to other programming languages. However, the fundamental mechanism remains the same — inheritance through prototypes.