Sobes.tech
Middle

What is prototype inheritance in JavaScript?

sobes.tech AI

Answer from AI

In JavaScript, objects inherit properties and methods from their prototypes. Each object's prototype is another object, whose properties and methods are accessible through the prototype chain.

When accessing a property of an object, JavaScript first looks for it directly on the object itself. If the property is not found, the search continues in the object's prototype, then in the prototype's prototype, and so on, until the property is found or the end of the chain is reached (null).

Prototypal inheritance differs from classical inheritance (as in Java or C++), where objects are created from classes that define their structure and behavior. In JavaScript, classes introduced in ES6 are syntactic sugar over prototypal inheritance.

Main aspects:

  • proto: An internal property of an object that points to its prototype.
  • prototype: A property of constructor functions that points to the object that will serve as the prototype for created instances.
  • Object.getPrototypeOf(obj): The standard way to get an object's prototype.
  • Object.setPrototypeOf(obj, proto): The standard way to set an object's prototype.

Example:

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

// Adding a method to Animal's prototype
Animal.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

// Creating an instance
const dog = new Animal("Buddy");

// Calling a method from the prototype
dog.sayHello(); // Output: Hello, my name is Buddy

// The prototype of dog is Animal.prototype
console.log(Object.getPrototypeOf(dog) === Animal.prototype); // Output: true

// The prototype of Animal.prototype is Object.prototype
console.log(Object.getPrototypeOf(Animal.prototype) === Object.prototype); // Output: true

// The end of the prototype chain is null
console.log(Object.getPrototypeOf(Object.prototype) === null); // Output: true

Comparison with classical inheritance (using ES6 classes):

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

  sayHello() {
    console.log(`Hello, my name is ${this.name}`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name); // Call the parent class constructor
    this.breed = breed;
  }

  bark() {
    console.log("Woof!");
  }
}

const buddy = new Dog("Buddy", "Golden Retriever");
buddy.sayHello(); // Output: Hello, my name is Buddy (inherited from Animal)
buddy.bark(); // Output: Woof! (Dog method)

// Classes in ES6 are syntactic sugar over prototypes
console.log(Object.getPrototypeOf(Dog) === Animal); // Output: true (inheritance via classes)
console.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // Output: true (method inheritance through prototypes)
console.log(Object.getPrototypeOf(buddy) === Dog.prototype); // Output: true (instance inherits from class prototype)

Prototypal inheritance is a key concept in JavaScript, and understanding it is essential for effective language use.