On this page

Prototypes & Inheritance

4 min read

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

js
1const animal = {
2 eat() { return "eating"; },
3};
4
5const dog = Object.create(animal); // dog's prototype is animal
6dog.bark = () => "woof";
7
8dog.bark(); // "woof" found on dog itself
9dog.eat(); // "eating" not on dog, found on animal through the chain
10dog.fly; // undefined, not found anywhere, the chain ends at null

The chain for an array looks like this:

1[1, 2, 3] → Array.prototype → Object.prototype → null

That is why arrays have map (from Array.prototype) and also toString and hasOwnProperty (from Object.prototype).

__proto__ vs prototype

These two names confuse everyone.

NameLives onMeaning
__proto__ (use Object.getPrototypeOf)Every objectThe actual link to its prototype
prototypeFunctions (constructors)The object that becomes the __proto__ of instances made with new
js
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; // true

Methods 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.

js
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

js
1dog.hasOwnProperty("bark"); // true
2dog.hasOwnProperty("eat"); // false (inherited)
3Object.hasOwn(dog, "eat"); // false, the modern, safer version
4
5for (const key in dog) { } // loops own AND inherited enumerable keys
6Object.keys(dog); // own keys only

Here 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.

js
1dog.eat = () => "barking instead"; // dog now has its own eat

Changing 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, so setState and render came 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, instanceof checks, and custom Error classes.

Summary

1Prototype → hidden link to another object, used for property lookup
2Prototype chain → follow the links until found, ends at null
3prototype (on functions) vs __proto__ (on objects) → template vs actual link
4Methods on prototype → shared by all instances
5class → clean syntax over prototypes, extends links the chain
6hasOwn / Object.keys → own properties, for...in includes inherited ones
7Prefer composition over inheritance in React

Next, how code is split across files and shared with import and export.

Next TopicES Modules & Imports