Loading...
Loading...
The chain of linked objects that powers JavaScript inheritance.
Module 6 · How JavaScript Works
Understanding the engine makes you a better debugger. Execution contexts, the call stack, hoisting, memory allocation, closures, and the prototype chain explain why JavaScript behaves the way it does under the hood.
Learn Prototype Chain in JavaScript — covering Chain Visualization, Built-in Chains, instanceof, Property Shadowing with interactive visual examples and step-by-step explanations.
JavaScript looks simple on the surface, but the engine does a lot of work behind the scenes. Variables are hoisted, functions create new execution contexts, the call stack tracks nested calls, and the prototype chain resolves property lookups.
This module is for developers who want to stop guessing and start understanding. Visual diagrams of the call stack, heap, and scope chain make abstract concepts concrete — and directly improve your debugging skills in real projects.
Understanding prototype chain is essential for every JavaScript developer. It shows up in frontend UI code, backend APIs, and framework internals — and getting it wrong leads to bugs that are hard to trace. This chapter builds intuition with visuals so the behavior sticks.
Objects linked in a chain, each inheriting from the next.
function Animal(name) { this.name = name; } Animal.prototype.eat = function() { return "eating"; }; function Dog(name, breed) { Animal.call(this, name); this.breed = breed; } Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; Dog.prototype.bark = function() { return "Woof!"; }; const rex = new Dog("Rex", "Lab");
rex → Dog.prototype → Animal.prototype → Object.prototype → null
Every value in JavaScript has a prototype chain.
// Arrays: [1,2,3].__proto__ === Array.prototype // true Array.prototype.__proto__ === Object.prototype // true // Chain: [1,2,3] → Array.prototype → Object.prototype → null // Strings: "hello".__proto__ === String.prototype // true // Chain: "hello" → String.prototype → Object.prototype → null // Functions: function foo() {} foo.__proto__ === Function.prototype // true // Chain: foo → Function.prototype → Object.prototype → null // That's why arrays have .map(), strings have .slice(), // and everything has .toString() — it's inherited!
| Value | Chain |
|---|---|
| [1, 2] | → Array.prototype → Object.prototype → null |
| "hello" | → String.prototype → Object.prototype → null |
| 42 | → Number.prototype → Object.prototype → null |
| function(){} | → Function.prototype → Object.prototype → null |
| {} | → Object.prototype → null |
Checks if an object's prototype chain contains a constructor's prototype.
function Animal() {} function Dog() {} Dog.prototype = Object.create(Animal.prototype); const rex = new Dog(); rex instanceof Dog; // true rex instanceof Animal; // true rex instanceof Object; // true // instanceof walks up the chain: // rex.__proto__ === Dog.prototype? ✓ → true // rex.__proto__.__proto__ === Animal.prototype? ✓ → true // Arrays: [] instanceof Array; // true [] instanceof Object; // true (Array inherits from Object)
💡 instanceof checks the entire chain, not just the direct prototype. For exact type checking, use Object.getPrototypeOf(obj) === X.prototype.
Own properties override inherited ones with the same name.
const parent = { color: "blue", size: 10 }; const child = Object.create(parent); child.color; // "blue" (inherited) child.color = "red"; // creates OWN property child.color; // "red" (own — shadows parent) parent.color; // "blue" (unchanged!)
Setting a property on the child creates an own property that 'shadows' the inherited one. The parent is never modified.
Adding methods to built-in prototypes (and why you usually shouldn't).
// You CAN add to built-in prototypes: Array.prototype.last = function() { return this[this.length - 1]; }; [1, 2, 3].last(); // 3 // But you SHOULDN'T because: // 1. Future JS versions might add a different .last() // 2. Libraries might conflict // 3. for...in loops will iterate over added properties // ✗ Don't modify: Object.prototype, Array.prototype, etc. // ✓ Instead, use utility functions or extend with classes
⚠️ Modifying built-in prototypes is called "monkey-patching". It causes maintenance nightmares. Only polyfills (adding missing standard features to old browsers) justify it.
Common questions about prototype chain.