Prototypes & Prototypal Inheritance
📖 Concept
Every JavaScript object has a hidden internal property called [[Prototype]] (accessible via __proto__ or Object.getPrototypeOf()). When you access a property that doesn't exist on an object, JavaScript looks up the prototype chain.
Prototype chain: object → object's prototype → prototype's prototype → ... → Object.prototype → null
This is JavaScript's inheritance model — prototypal inheritance. Unlike classical inheritance (classes in Java/C++), objects inherit directly from other objects.
Constructor functions + .prototype = the traditional way to create "classes" before ES6.
🏠 Real-world analogy: Prototypes are like family traits. If you don't have blue eyes (own property), check if your parent does (prototype). If they don't, check grandparent. Keep going up the family tree.
💻 Code Example
1// Every object has a prototype2const arr = [1, 2, 3];3// arr → Array.prototype → Object.prototype → null4console.log(arr.__proto__ === Array.prototype); // true5console.log(arr.__proto__.__proto__ === Object.prototype); // true67// Constructor functions (pre-ES6 classes)8function Animal(name, sound) {9 this.name = name;10 this.sound = sound;11}12// Methods on prototype (shared across all instances — memory efficient!)13Animal.prototype.speak = function() {14 return `${this.name} says ${this.sound}`;15};16const dog = new Animal("Rex", "Woof");17console.log(dog.speak()); // "Rex says Woof"18console.log(dog.hasOwnProperty("name")); // true (own property)19console.log(dog.hasOwnProperty("speak")); // false (inherited from prototype)2021// Prototypal inheritance22function Dog(name) {23 Animal.call(this, name, "Woof"); // Call parent constructor24}25Dog.prototype = Object.create(Animal.prototype); // Set up prototype chain26Dog.prototype.constructor = Dog; // Fix constructor reference27Dog.prototype.fetch = function() {28 return `${this.name} fetches the ball!`;29};30const rex = new Dog("Rex");31console.log(rex.speak()); // "Rex says Woof" (inherited)32console.log(rex.fetch()); // "Rex fetches the ball!" (own)3334// Object.create — direct prototypal inheritance35const personProto = {36 greet() { return `Hi, I'm ${this.name}`; }37};38const alice = Object.create(personProto);39alice.name = "Alice";40console.log(alice.greet()); // "Hi, I'm Alice"4142// Checking the prototype chain43console.log(rex instanceof Dog); // true44console.log(rex instanceof Animal); // true45console.log(rex instanceof Object); // true
🏋️ Practice Exercise
Mini Exercise:
- Create a constructor function
Vehiclewith adrive()method on its prototype - Create
Carthat inherits fromVehicleand adds ahonk()method - Verify the prototype chain using
instanceofandObject.getPrototypeOf() - Add a method to
Array.prototype(then understand why this is dangerous)
⚠️ Common Mistakes
Adding methods directly to instances instead of the prototype — wastes memory for each instance
Modifying
Object.prototypeorArray.prototype— affects ALL objects/arrays globally!Forgetting to set
constructorafterDog.prototype = Object.create(Animal.prototype)Confusing
__proto__(instance's link to its prototype) with.prototype(constructor's blueprint for instances)Using
for...initerates over inherited properties — always checkhasOwnProperty()or useObject.hasOwn()
💼 Interview Questions
🎤 Mock Interview
Mock interview is powered by AI for Prototypes & Prototypal Inheritance. Login to unlock this feature.