Skip to content
GeeksSmith
intermediate 9 min read

Prototypes, Prototype Chain, and Class Inheritance

JavaScript uses prototypal inheritance where objects hold an internal [[Prototype]] reference to another object. Property lookups traverse up this prototype chain until found or null is reached.

Why it matters in interviews

Underneath modern ES6 'class' syntax lies JavaScript's prototype system. Understanding how methods are shared on prototypes rather than duplicated per instance is vital for memory optimization in large frontend apps.

Visual & Interactive Explanation

Interactive Flow Execution

Code Examples & Implementation

Prototypal Inheritance vs ES6 Classes (Memory Comparison)
// ❌ BAD: Re-creates getName function for every instance (10,000 users = 10,000 function objects)
function UserBad(name: string) {
  this.name = name;
  this.getName = function() { return this.name; };
}

// ✅ GOOD: Shares single function reference on User.prototype across all instances
function UserGood(name: string) {
  this.name = name;
}
UserGood.prototype.getName = function() {
  return this.name;
};

// ES6 Class Equivalent (desugars directly to UserGood.prototype.getName)
class UserClass {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
  getName() {
    return this.name;
  }
}

// Prototypal Subclassing with Object.create
function Admin(name: string, permissions: string[]) {
  UserGood.call(this, name); // Super constructor call
  this.permissions = permissions;
}
Admin.prototype = Object.create(UserGood.prototype);
Admin.prototype.constructor = Admin;

Interview-Ready Answers

Every JavaScript object has an internal [[Prototype]] link. When accessing a property, the V8 engine checks the instance first, then its prototype, and continues up the chain until null.

Official Documentation & Specifications

Follow-up Questions & Deep Dives

🎯 Code Output — What Does This Print?

Question 1medium
function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function() {
  return this.name + " makes a sound";
};

const dog = new Animal("Rex");
console.log(dog.speak());
console.log(dog.hasOwnProperty("speak"));
console.log(dog.hasOwnProperty("name"));
Question 2hard
function A() {}
function B() {}

B.prototype = Object.create(A.prototype);

const b = new B();
console.log(b instanceof B);
console.log(b instanceof A);
console.log(b instanceof Object);
Question 3tricky
const parent = { x: 1 };
const child = Object.create(parent);
child.y = 2;

console.log(child.x);
console.log(child.y);
console.log("x" in child);
console.log(child.hasOwnProperty("x"));
Question 4hard
function Foo() {}
Foo.prototype.x = 10;

const a = new Foo();
const b = new Foo();

a.x = 20;

console.log(a.x);
console.log(b.x);
delete a.x;
console.log(a.x);

Common Mistakes & Anti-Patterns

  • Defining methods inside constructor functions or React component render functions instead of prototype/memoized handlers.
  • Modifying native prototypes like Array.prototype (prototype mutation breaks engine optimizations and third-party code).
  • Confusing the function property 'MyFunc.prototype' with the object link 'obj.__proto__'.

Real-World Architectural Scenario

A high-frequency financial grid instantiates 50,000 row model objects. Memory usage spiked to 300MB. How do prototypes solve this?

Rate Your Readiness

Rate how comfortably you can explain this in an interview to update your global readiness gauge:

Rate your confidence: