🧬 Prototypal Inheritance

How JavaScript resolves properties by walking the prototype chain

// The prototype chain for an Animal object:
🐕 dog (instance)
Object
name: "Buddy"
breed: "Labrador"
__proto__: → Dog.prototype
[[Prototype]]
🐶 Dog.prototype
prototype
bark: fn() { "Woof!" }
fetch: fn() { ... }
__proto__: → Animal.prototype
[[Prototype]]
🦎 Animal.prototype
prototype
breathe: fn() { ... }
eat: fn() { ... }
__proto__: → Object.prototype
[[Prototype]]
📦 Object.prototype
root
toString: fn()
hasOwnProperty: fn()
__proto__: → null
null — end of chain

🔍 Property Lookup Simulator

Click a property to watch JS walk the chain to find it:
👉Select a property above to start the lookup simulation
// result will appear here
🧠 Key insight: When you access dog.breathe(), JavaScript first looks in the dog object itself. Not found → checks Dog.prototype. Not there → checks Animal.prototype. Found! It's breathe. This chain walk happens on every property access in JavaScript — even for built-ins.
ES6 class (sugar)
class Dog extends Animal {
  constructor(name) {
    super(name);
  }
  bark() { return "Woof"; }
}
// syntactic sugar over prototypes
What it compiles to
Dog.prototype = Object.create(
  Animal.prototype);
Dog.prototype.bark = function() {
  return "Woof";
};
// prototype chain, same result