JavaScript Prototype Chain: How Inheritance Really Works in JS

JavaScript Prototype Chain: How Inheritance Really Works in JS

JavaScript uses prototypal inheritance — every object has a hidden link to another object called its prototype. When you access a property, JavaScript walks up the chain until it finds it or reaches null. Understanding this makes inheritance, mixins, and the class syntax all click into place at once.

TL;DR: Every object has [[Prototype]] (accessible via Object.getPrototypeOf()). Property lookup walks the chain until found or null. Constructor function .prototype becomes instances [[Prototype]]. class syntax is sugar over this. __proto__ is deprecated — use Object.create() or Object.getPrototypeOf().

How prototype lookup works

const animal = {
  breathe() { return this.name + ' is breathing'; }
};

const dog = Object.create(animal); // dog.[[Prototype]] = animal
dog.name = 'Rex';
dog.bark = () => 'woof';

// Property lookup:
dog.bark();    // 'woof' — found on dog itself
dog.breathe(); // 'Rex is breathing' — NOT on dog, found on animal
dog.toString(); // found on Object.prototype (top of chain)

// Chain: dog → animal → Object.prototype → null
Object.getPrototypeOf(dog) === animal;         // true
Object.getPrototypeOf(animal) === Object.prototype; // true
Object.getPrototypeOf(Object.prototype) === null;   // true

.prototype vs [[Prototype]]

// Constructor function .prototype = template for instances
function Person(name) { this.name = name; }
Person.prototype.greet = function() { return 'Hi, I am '+this.name; };

const alice = new Person('Alice');
alice.greet(); // Works! From Person.prototype

// new keyword does:
// 1. Creates empty object {}
// 2. Sets [[Prototype]] = Person.prototype
// 3. Calls Person with this = new object
// 4. Returns the object

// .prototype (on function): used as [[Prototype]] for new instances
// [[Prototype]] (on object): the actual chain link
alice.__proto__ === Person.prototype; // true (same as getPrototypeOf)

Class syntax — sugar over prototypes

class Animal {
  constructor(name) { this.name = name; }
  speak() { return this.name + ' makes a sound'; }
}

class Dog extends Animal {
  speak() { return this.name + ' barks'; }
  fetch() { return this.name + ' fetches!'; }
}

const dog = new Dog('Rex');
dog.speak();  // 'Rex barks' — overridden
dog.fetch();  // 'Rex fetches!' — own method

// Class IS just prototype sugar:
// Animal.prototype.speak exists
// Dog.prototype.[[Prototype]] === Animal.prototype
// dog.[[Prototype]] === Dog.prototype

Mixins — sharing behavior without inheritance

// Problem: inheritance is single-parent
// Solution: copy methods from multiple sources
const Serializable = {
  toJSON() { return JSON.stringify(this); },
  fromJSON(json) { return Object.assign(Object.create(this),JSON.parse(json));}
};

const Validatable = {
  validate() { return this.rules.every(r=>r(this)); }
};

class User {}
Object.assign(User.prototype, Serializable, Validatable);
// User instances now have toJSON, fromJSON, validate
// Multiple mixins without deep inheritance hierarchy
  • ✅ Object.getPrototypeOf() over deprecated __proto__
  • ✅ Object.create(proto) for explicit prototype setting
  • ✅ class extends is just prototype chain sugar
  • ✅ Mixins for sharing behavior without tight coupling
  • ❌ Never mutate Object.prototype — breaks all objects
  • ❌ Deep inheritance hierarchies — prefer composition

External reference: MDN Prototype Chain.

Recommended Reading

Designing Data-Intensive Applications — The bible of distributed systems and production engineering at scale.

The Pragmatic Programmer — Timeless engineering wisdom every senior developer needs.

Affiliate links. We earn a small commission at no extra cost to you.

Free Weekly Newsletter

🚀 Join 2,000+ Senior Developers

Get expert-level JavaScript, Python, AWS, system design and AI secrets every week. Zero fluff, pure signal.

✓ No spam✓ Unsubscribe anytime✓ Expert-level only

Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply