JavaScript Prototypal Inheritance Explained: How It Works and Differences from Classical Inheritance

everything you need to know about prototypal inheritance in JavaScript, including prototypes, prototype chain, delegation patterns, ES6 classes under the hood, classical vs prototypal differences, use cases, and common pitfalls.


1. Core Concept & Prototype Chain

  • Every JavaScript object has an internal [[Prototype]] (accessible via __proto__ or Object.getPrototypeOf).
  • Prototypal inheritance means objects delegate property access to their prototype object.
js
1const parent = { greet() { return 'Hello'; } }; 2const child = Object.create(parent); 3console.log(child.greet()); // "Hello"

2. Creating Inheritance

Object.create

js
1const animal = { speak() { console.log('...'); } }; 2const dog = Object.create(animal); 3dog.speak(); // "..."

Constructor Functions

js
1function Person(name) { this.name = name; } 2Person.prototype.sayName = function() { 3 console.log(this.name); 4}; 5const alice = new Person('Alice'); 6alice.sayName(); // "Alice"

ES6 Classes (Syntactic Sugar)

js
1class Vehicle { 2 constructor(type) { this.type = type; } 3 describe() { console.log(this.type); } 4} 5class Car extends Vehicle { 6 drive() { console.log('Driving'); } 7} 8const c = new Car('Sedan'); 9c.describe(); // "Sedan"

3. Prototypal vs Classical

AspectPrototypal InheritanceClassical Inheritance
MechanismObjects delegate to other objectsClasses define blueprints and hierarchies
SyntaxObject.create, __proto__class, extends, super
DynamicsHighly dynamic; modify at runtimeMore static; class definitions fixed
InstantiationDelegation-basedConstruction via new and constructors
FlexibilityMixins & delegationStructured hierarchy

4. Use Cases

  • Object Composition & Mixins: share behavior across unrelated objects.
  • Dynamic Extensions: add or override methods at runtime.
  • Polymorphism: delegate to different prototypes for variation.

5. Common Pitfalls

  • Overwriting Prototype: resetting a constructor’s prototype can break the constructor link.
  • Modifying Built-ins: altering Array.prototype or Object.prototype can lead to global conflicts.
  • Confusing __proto__ vs prototype: the former is on instances, the latter on constructor functions.

6. Summary Table

FeaturePrototypalClassical
DefinitionObjects inherit directly via prototypeClasses and instances via constructors
Prototype Chain[[Prototype]] linkClass hierarchy under the hood
Runtime DynamicsCan change at runtimeFixed structure after definition
Syntax FlexibilityProcedural/object-basedDeclarative class syntax
Method SharingShared on prototype objectShared on class prototype

Use Object.create for simple delegation patterns.
Favor composition (mixins) over deep inheritance chains.
❌ Avoid modifying built-in prototypes in production.