JavaScript Prototype Chain: How Inheritance Really Works in JS

JavaScript Prototype Chain: How Inheritance Really Works in JS
3 views

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. This guide focuses on JavaScript prototype chain, with the production trade-offs senior engineers need to make sound decisions.

⚡ 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 — JavaScript prototype chain

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

Related: TypeScript for JavaScript Developers: The Migration Guide That Actually Works · JavaScript Closures, Scope, and the Module Pattern: The Complete Guide · JavaScript Promises: The Complete Guide From Basics to Advanced Patterns

Related: JavaScript Async/Await: Every Pattern, Pitfall, and Performance Trick · How HTTPS Works: TLS, Certificates, and Encryption Explained for Developers · OAuth 2.0 and JWT Explained: How Authentication Actually Works in Production

Deep-dive PDF

Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.

Already subscribed? or open the subscribe page.


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 comment

No account needed. Name and email are optional.