Prototypes & Inheritance
You will not write prototypes by hand in modern React, but interviewers ask about them to test whether you understand how JavaScript objects and classes really work.
Definition
Every JavaScript object has a hidden link to another object called its prototype. When you read a property that the object does not have, JavaScript follows that link and looks in the prototype, then the prototype's prototype, and so on. This chain is the prototype chain. It ends at null.
Analogy: a student asks "do you have a pen?" If they do not, they ask their desk partner, then the whole class, then the teacher. The first one who has it answers.
How It Works
1const animal = {2 eat() { return "eating"; },3};4 5const dog = Object.create(animal); // dog's prototype is animal6dog.bark = () => "woof";7 8dog.bark(); // "woof" found on dog itself9dog.eat(); // "eating" not on dog, found on animal through the chain10dog.fly; // undefined, not found anywhere, the chain ends at nullThe chain for an array looks like this:
1[1, 2, 3] → Array.prototype → Object.prototype → nullThat is why arrays have map (from Array.prototype) and also toString and hasOwnProperty (from Object.prototype).
__proto__ vs prototype
These two names confuse everyone.
| Name | Lives on | Meaning |
|---|---|---|
__proto__ (use Object.getPrototypeOf) | Every object | The actual link to its prototype |
prototype | Functions (constructors) | The object that becomes the __proto__ of instances made with new |
1function Person(name) { this.name = name; }2Person.prototype.hi = function () { return "hi " + this.name; };3 4const p = new Person("Asha");5p.hi(); // "hi Asha"6Object.getPrototypeOf(p) === Person.prototype; // trueMethods live once on the prototype and are shared by every instance. That saves memory compared with creating a copy of each method per object.
Classes Are Sugar
class syntax is a cleaner way to write the same prototype setup.
1class Animal {2 constructor(name) { this.name = name; }3 speak() { return this.name + " makes a sound"; }4}5 6class Dog extends Animal {7 speak() { return super.speak() + ": woof"; }8}9 10new Dog("Rex").speak(); // "Rex makes a sound: woof"Under the hood, Dog.prototype links to Animal.prototype. typeof Dog is still "function".
Own vs Inherited Properties
1dog.hasOwnProperty("bark"); // true2dog.hasOwnProperty("eat"); // false (inherited)3Object.hasOwn(dog, "eat"); // false, the modern, safer version4 5for (const key in dog) { } // loops own AND inherited enumerable keys6Object.keys(dog); // own keys onlyHere is what breaks. for...in also walks inherited properties, so use Object.keys or Object.entries when you want only the object's own data.
Shadowing and Mutation Risks
Writing a property always creates it on the object itself. It shadows the prototype's value and does not change the prototype.
1dog.eat = () => "barking instead"; // dog now has its own eatChanging built-in prototypes, like adding a method to Array.prototype, affects every array in the program. This is called monkey patching, and it is risky. Polyfills do it carefully, only when the method is missing.
Inheritance vs Composition
Deep inheritance trees become fragile. React's guidance is composition over inheritance: build components by combining smaller ones with props and children, not by extending a base component class.
In React
- Class components used
extends React.Component, sosetStateandrendercame from the prototype chain. - Modern React uses function components and hooks, so you rarely touch prototypes.
- You still meet them in interviews, in error messages like "x is not a function", and when working with libraries,
instanceofchecks, and customErrorclasses.
Summary
1Prototype → hidden link to another object, used for property lookup2Prototype chain → follow the links until found, ends at null3prototype (on functions) vs __proto__ (on objects) → template vs actual link4Methods on prototype → shared by all instances5class → clean syntax over prototypes, extends links the chain6hasOwn / Object.keys → own properties, for...in includes inherited ones7Prefer composition over inheritance in ReactNext, how code is split across files and shared with import and export.