How does prototypal inheritance work in JavaScript?
Take a moment.
Say your answer out loud or write it down first — retrieval is what makes it stick. Reveal when you're ready.
Short answer
Every object has an internal [[Prototype]] link. Property lookups walk this chain from the object upward until found or null. Objects inherit directly from other objects — classes are syntactic sugar over the same mechanism.
Detailed explanation
When you read obj.x, the engine checks obj itself, then its prototype via Object.getPrototypeOf(obj), then that object's prototype, and so on up the chain until it hits null. Writes create properties on the receiving object rather than mutating ancestors. The chain gets established by Object.create(proto), constructors' hidden prototype linkage, or class extends. ES6 classes don't change the runtime model — class Dog extends Animal compiles to the same prototype wiring with nicer syntax and stricter rules. Key related methods: hasOwnProperty / Object.hasOwn distinguish own vs inherited keys; Object.keys ignores the chain entirely. Practical modern relevance is mostly conceptual — understanding why instances share methods without copying them, how polyfills attach to built-in prototypes (Array.prototype.at), and why extending native prototypes is risky.
Example
const animal = {
eat() { return `${this.name} eats`; },
};
const dog = Object.create(animal); // dog's prototype is animal
dog.name = 'Rex';
dog.bark = () => 'Woof';
console.log(dog.eat()); // found on animal via the chain
console.log(Object.hasOwn(dog, 'eat')); // false — inherited
console.log(Object.hasOwn(dog, 'name')); // true — ownInterview tip
Walk the lookup algorithm step by step, then drop 'classes are sugar over prototypes' — concise and signals you understand what the syntax actually does.
Common mistakes
- Describing prototypal inheritance as copies of classes.
- Not knowing Object.create sets the prototype link directly.