2 min read

Prototypes and Inheritance

JavaScript is a prototype-based language, meaning that objects can inherit properties and methods from other objects. This is different from class-based inheritance found in languages like Java or C++.

1. The Prototype Chain

Every JavaScript object has a special hidden property, <a href='/Prototype'>Prototype</a> (often exposed as __proto__ in browsers), which is either null or references another object. That object is called "a prototype".

When you try to access a property of an object:

  1. The engine searches the object itself.
  2. If not found, it searches the object's prototype.
  3. If not found, it searches the prototype's prototype.
  4. This continues until the end of the chain is reached (usually Object.prototype, whose prototype is null).
const animal = {
  eats: true,
  walk() {
    console.log("Animal walks");
  }
};

const rabbit = {
  jumps: true
};

// Set rabbit's prototype to animal
rabbit.__proto__ = animal;

// rabbit can now use properties from animal
console.log(rabbit.eats); // true
rabbit.walk(); // "Animal walks"

2. F.prototype

When you create objects using a constructor function (using new), the prototype property of that function determines the prototype of the created object.

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

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

const john = new Person("John");
john.sayHello(); // "Hello, my name is John"

// john.__proto__ === Person.prototype

3. Object.create()

The modern way to create an object with a specific prototype is Object.create().

const animal = {
  eats: true
};

const rabbit = Object.create(animal);
rabbit.jumps = true;

console.log(rabbit.eats); // true

4. Classes (ES6)

ES6 introduced the class keyword, but it is primarily syntactic sugar over the existing prototype-based inheritance.

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {
  speak() {
    console.log(`${this.name} barks.`);
  }
}

const d = new Dog('Mitzie');
d.speak(); // "Mitzie barks."

Under the hood, Dog.prototype inherits from Animal.prototype.

programming/javascript/vanilla/javascript programming/javascript/vanilla/es6-features