Skip to main content

Prototype chain

The prototype chain is a JavaScript inheritance mechanism through which, when accessing a property or method, an object looks for it not only on itself, but also on its "parents" (prototypes).


In short

Every object in JS has a hidden reference to another object, its prototype ([[Prototype]]), and if the needed property is not found on the object itself, JS looks for it in the prototype, then in the prototype's prototype, and so on, until it reaches null.

This sequence is called the prototype chain.


Example - basic

javascript
const animal = { eats: true }; const dog = Object.create(animal); // dog inherits from animal dog.barks = true; console.log(dog.barks); // true (found on dog) console.log(dog.eats); // true (found on animal) console.log(dog.toString); // [Function: toString] (inherited from Object.prototype)

What happens:

javascript
dog -> animal -> Object.prototype -> null

JS walks the chain:

  1. Looks for barks on dog -> found
  2. Looks for eats on dog -> not found -> goes to animal -> found
  3. Looks for toString -> not on animal -> goes to Object.prototype -> found
  4. Next, Object.prototype.__proto__ is null -> end of the chain

Visually

javascript
dog { barks: true } ^ animal { eats: true } ^ Object.prototype { toString(), hasOwnProperty(), ... } ^ null

Example with methods

javascript
const animal = { walk() { console.log('The animal walks'); } }; const dog = Object.create(animal); dog.bark = function() { console.log('Woof!'); }; dog.walk(); // "The animal walks" (the method is found on the prototype) dog.bark(); // "Woof!" (the method is found on dog)

JS does not copy methods, it finds them at call time by walking the chain.


Checking the prototype

javascript
console.log(Object.getPrototypeOf(dog) === animal); // true

You can also check it with the instanceof operator:

javascript
console.log(dog instanceof Object); // true (because Object.prototype is in the chain)

Example with classes (the same principle)

javascript
class Animal { eat() { console.log('Eating'); } } class Dog extends Animal { bark() { console.log('Woof'); } } const rex = new Dog(); rex.bark(); // "Woof" rex.eat(); // "Eating" (inherited from Animal)

Under the hood it's the same mechanism:

javascript
rex -> Dog.prototype -> Animal.prototype -> Object.prototype -> null

If a property is found, the search stops

javascript
const animal = { eats: true }; const dog = Object.create(animal); dog.eats = false; console.log(dog.eats); // false (found on dog itself, does not search further)

JS always uses the first property found in the chain.


You can change the prototype manually (but it's not advisable)

javascript
const cat = { meow: true }; Object.setPrototypeOf(dog, cat); console.log(dog.meow); // true

This lets you rebuild the chain, but it is slow and is usually not recommended in production.


Summary

StageWhat happens
1JS looks for the property on the object itself
2If not found, it goes to the prototype ([[Prototype]])
3Then to the prototype's prototype
4And so on, until it reaches null
If not found anywhereReturns undefined

Example of the final scheme

javascript
rex -> Dog.prototype -> Animal.prototype -> Object.prototype -> null
LevelWhere it's storedExample
rexown propertiesrex.name = 'Rex'
Dog.prototypemethods of the Dog classbark()
Animal.prototypemethods of the base classeat()
Object.prototypestandard methodstoString(), hasOwnProperty()

In one phrase:

The prototype chain is the path along which JavaScript looks for properties and methods, moving from an object to its prototype, until it finds what it needs or reaches null.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.