Q20 of 40 · JavaScript
How does prototypal inheritance work in JavaScript, and how does `class` relate to it?
Short answer
Short answer: Every object has an internal `[[Prototype]]` reference. Property lookups traverse the chain until found or null. `class` syntax is syntactic sugar — methods are placed on `ClassName.prototype`, shared across all instances, not copied. Understanding this explains `instanceof`, `hasOwnProperty`, and prototype mutation effects.
Detail
JavaScript uses prototype-based inheritance rather than classical inheritance. Objects inherit from objects directly.
Prototype chain: When you access obj.foo, JS checks obj itself, then Object.getPrototypeOf(obj), then its prototype, up to null. This is the prototype chain lookup.
Constructor functions and .prototype: When you call new Fn(), the created object's [[Prototype]] is set to Fn.prototype. Methods on Fn.prototype are shared across all instances — not copied — which is memory-efficient.
class syntax: ES6 class desugars to constructor functions + prototype assignments. class Dog extends Animal sets Dog.prototype.__proto__ = Animal.prototype and handles the super call. The prototype chain is identical underneath.
Implications for testing: Understanding prototype chains helps debug unexpected property access — why hasOwnProperty vs in behave differently, and why adding to a constructor's prototype after instantiation still affects all existing instances.
// EXAMPLE
// Manual prototype chain
const animal = { eat() { return "eating"; } };
const dog = Object.create(animal);
dog.bark = () => "woof";
console.log(dog.eat()); // "eating" — found on animal prototype
console.log(dog.hasOwnProperty("eat")); // false
console.log(dog.hasOwnProperty("bark")); // true
console.log(Object.getPrototypeOf(dog) === animal); // true
// class — same mechanism
class Animal {
eat() { return "eating"; }
}
class Dog extends Animal {
bark() { return "woof"; }
}
const fido = new Dog();
console.log(fido.eat()); // traverses prototype chain
console.log(fido instanceof Dog); // true
console.log(fido instanceof Animal); // true