CrackFrontendCF
Resources
Practice
CrackFrontend

Your guide to mastering frontend interviews

Resources

LibraryPracticeDonate

Company

About UsContact

Legal

Privacy PolicyTerms of Service

Built with ❀️ by Tushar Khanna

CrackFrontendCF
Resources
Practice

πŸ”— Prototype and Prototype Inheritance in JavaScript

Prototypes enable inheritance in JavaScript by linking objects through a chain. Foundation for understanding how JavaScript objects share properties and methods.

Interview Importance: πŸ”΄ Critical β€” Asked in 90% of JavaScript interviews. Understanding prototypes is fundamental to understanding how JavaScript works under the hood. -- 1️⃣ What is a Prototype? JavaScript uses prototype-based inheritance, meaning objects inherit properties and methods from other objects via the chain β€” not through classical class-based inheritance like Java or C++. Core Concept Every JavaScript object has an internal link to another object called its prototype. When you access a property on an object, JavaScript first looks at the object itself. If not found, it looks up the prototype chain until it finds the property or reaches . -- 2️⃣ Why Do Prototypes Matter? Memory Efficiency Without prototypes, each object instance would have its own copy of every method: Real-World Impact 1000 instances without prototype: 1000 function objects in memory 1000 instances with prototype: 1 shared function object -- 3️⃣ How Prototypes Work β€” Step by Step 3.1 The Property (Functions) Every JavaScript function has a property (an object) that becomes the prototype of instances created with . πŸ” Dry Run: What happens when is called? 3.2 The Property (Objects) Every object has a property pointing to its prototype. This is how the chain is traversed. 3.3 Visualizing the Chain -- 4️⃣ Prototype Inheritance (Extending) Using Object.create() πŸ” Dry Run: Prototype Chain After Inheritance Why Each Step Matters Code Add methods to ❌ Common Mistake: Using Instead of -- 5️⃣ ES6 Class Syntax (Syntactic Sugar) ES6 is syntactic sugar over prototype-based inheritance: Under the Hood β€” Same Prototype Chain! -- 6️⃣ Key Methods for Working with Prototypes Purpose Create object with specified prototype Get an object's prototype Set an object's prototype (slow!) Check if property exists on object (not prototype) Check if property exists anywhere in chain Check if object is instance of constructor -- 7️⃣ Method Overriding (Shadowing) When you define a method on an object or its prototype that already exists higher in the chain: πŸ” Dry Run: Property Lookup with Shadowing -- 8️⃣ Common Interview Questions Q1: What is the difference between and ? Answer: is a property of functions β€” it becomes the prototype of instances created with is a property of all objects β€” it points to the object's actual prototype Q2: How do you check if a property is on the object vs the prototype? Answer: Q3: What happens if you modify a built-in prototype like Array.prototype? Answer: It affects ALL arrays in your application (prototype pollution). This is generally discouraged: Q4: Explain and how it works Answer: checks if an object's prototype chain contains : Q5: What is the output? Answer: Both are because points to the shared object, which is both and . -- 9️⃣ Common Pitfalls Pitfall 1: Forgetting to Reset Constructor Pitfall 2: Arrow Functions Don't Have Pitfall 3: Modifying Prototype After Creating Instances -- πŸ”Ÿ Summary Description An object from which other objects inherit properties Internal link to an object's prototype Prototype Chain Create object with specified prototype ES6 Classes Key Takeaways 1. Every object has a prototype (except which is ) 2. Methods on prototype are shared β€” memory efficient 3. Property lookup walks the chain β€” own properties checked first 4. is syntactic sugar β€” same prototype mechanism underneath 5. Use for inheritanceβ€” not -- πŸ“š Further Reading MDN: Inheritance and the prototype chain JavaScript.info: Prototypes -- <!-quiz-start --Q1: What is the difference between and ? [ ] They are the same thing [ ] is only available in Node.js [x] is a property of functions; is a property of all objects pointing to their prototype [ ] is deprecated and should be used instead Q2: What happens when you access a property that doesn't exist on an object? [ ] JavaScript throws a ReferenceError [ ] JavaScript returns null [x] JavaScript looks up the prototype chain until it finds the property or reaches null [ ] JavaScript creates the property automatically Q3: Why should you use instead of when setting up inheritance? [ ] is faster [ ] doesn't work with prototypes [x] creates the prototype link without calling the parent constructor [ ] There is no difference between the two approaches <!-quiz-end --
JavaScriptCore Concepts
πŸ›‘ AbortController: Canceling Async Operations in JavaScript
medium
πŸ”’ Closures in JavaScript β€” The Complete Guide
hard
πŸ“¦ Understanding ES6 Modules in JavaScript
medium
⚑ JavaScript Event Loop: Complete Guide to Asynchronous Execution
hard
🧭 Arrow Functions vs Function Declarations in JavaScript
easy
πŸ—‘οΈ Garbage Collection in JavaScript β€” Memory Management & Leak Prevention
hard
πŸ—οΈ Constructor Functions in JavaScript
medium
πŸ‘οΈ MutationObserver: Watching DOM Changes in JavaScript
medium
πŸ” Understanding `of` in JavaScript – `for...of` Loop Deep Dive
hard
πŸ”— Prototype and Prototype Inheritance in JavaScript
medium
πŸ•΅οΈ What Are Proxies in JavaScript? (With Practical Use Cases)
medium
🎯 Scope in JavaScript β€” The Complete Guide
hard
πŸ”„ Script Loading: async vs defer vs Both
hard
πŸ“€ JavaScript Spread Operator (...) Explained
easy
🎯 The JavaScript `this` Keyword: Complete Guide to Context Binding
medium
10 of 15
LibraryJavaScriptCore Concepts10 of 61

πŸ”— Prototype and Prototype Inheritance in JavaScript

jsgeneral-conceptsmedium

Interview Importance: πŸ”΄ Critical β€” Asked in 90% of JavaScript interviews. Understanding prototypes is fundamental to understanding how JavaScript works under the hood.


1️⃣ What is a Prototype?

JavaScript uses prototype-based inheritance, meaning objects inherit properties and methods from other objects via the prototype chain β€” not through classical class-based inheritance like Java or C++.

Core Concept

Every JavaScript object has an internal link to another object called its prototype. When you access a property on an object, JavaScript first looks at the object itself. If not found, it looks up the prototype chain until it finds the property or reaches null.

+-----------------+
|   Your Object   |
|  { name: "X" }  |
+--------+--------+
         | [[Prototype]]
         β–Ό
+-----------------+
| Parent Prototype|
|  { greet() }    |
+--------+--------+
         | [[Prototype]]
         β–Ό
+-----------------+
| Object.prototype|
| { toString() }  |
+--------+--------+
         | [[Prototype]]
         β–Ό
        null

2️⃣ Why Do Prototypes Matter?

Memory Efficiency

Without prototypes, each object instance would have its own copy of every method:

// ❌ Without prototypes - each instance has its own copy
function PersonBad(name) {
  this.name = name;
  this.greet = function() {  // New function created for EACH instance
    console.log(`Hello, ${this.name}`);
  };
}

const p1 = new PersonBad("Alice");
const p2 = new PersonBad("Bob");
console.log(p1.greet === p2.greet); // false - Different function objects!

// βœ… With prototypes - all instances share the same method
function PersonGood(name) {
  this.name = name;
}
PersonGood.prototype.greet = function() {
  console.log(`Hello, ${this.name}`);
};

const p3 = new PersonGood("Alice");
const p4 = new PersonGood("Bob");
console.log(p3.greet === p4.greet); // true - Same function object!

Real-World Impact

  • 1000 instances without prototype: 1000 function objects in memory
  • 1000 instances with prototype: 1 shared function object

3️⃣ How Prototypes Work β€” Step by Step

3.1 The prototype Property (Functions)

Every JavaScript function has a prototype property (an object) that becomes the prototype of instances created with new.

function Person(name, age) {
  this.name = name;
  this.age = age;
}

// Adding method to the prototype
Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name} and I'm ${this.age} years old.`);
};

// Creating instances
const person1 = new Person("Alice", 25);
const person2 = new Person("Bob", 30);

person1.greet(); // Hello, I'm Alice and I'm 25 years old.
person2.greet(); // Hello, I'm Bob and I'm 30 years old.

πŸ” Dry Run: What happens when person1.greet() is called?

Step 1: JavaScript looks for `greet` on person1 object
        -> person1 = { name: "Alice", age: 25 }
        -> `greet` NOT found on person1

Step 2: JavaScript looks up the prototype chain
        -> person1.__proto__ === Person.prototype
        -> Person.prototype = { greet: function() {...} }
        -> `greet` FOUND!

Step 3: Execute greet() with `this` = person1
        -> Output: "Hello, I'm Alice and I'm 25 years old."

3.2 The __proto__ Property (Objects)

Every object has a __proto__ property pointing to its prototype. This is how the chain is traversed.

console.log(person1.__proto__ === Person.prototype);  // true
console.log(Person.prototype.__proto__ === Object.prototype);  // true
console.log(Object.prototype.__proto__);  // null (end of chain)

3.3 Visualizing the Chain

const person1 = new Person("Alice", 25);

// The prototype chain:
person1
  +-- __proto__ -> Person.prototype
                    +-- __proto__ -> Object.prototype
                                      +-- __proto__ -> null

4️⃣ Prototype Inheritance (Extending)

Using Object.create()

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function() {
  console.log(`Hello, I'm ${this.name}`);
};

function Employee(name, age, job) {
  Person.call(this, name, age);  // Step 1: Call parent constructor
  this.job = job;
}

// Step 2: Set up prototype chain
Employee.prototype = Object.create(Person.prototype);

// Step 3: Fix the constructor reference
Employee.prototype.constructor = Employee;

// Step 4: Add Employee-specific methods
Employee.prototype.work = function() {
  console.log(`${this.name} is working as a ${this.job}`);
};

// Usage
const emp = new Employee("Charlie", 28, "Engineer");
emp.greet();  // "Hello, I'm Charlie" (inherited)
emp.work();   // "Charlie is working as a Engineer" (own method)

πŸ” Dry Run: Prototype Chain After Inheritance

emp (instance)
|   { name: "Charlie", age: 28, job: "Engineer" }
|
+-- __proto__ -> Employee.prototype
                |   { constructor: Employee, work: fn }
                |
                +-- __proto__ -> Person.prototype
                                |   { constructor: Person, greet: fn }
                                |
                                +-- __proto__ -> Object.prototype
                                                |   { toString, hasOwnProperty, ... }
                                                |
                                                +-- __proto__ -> null

Why Each Step Matters

StepCodePurpose
1Person.call(this, name, age)Initialize parent properties on this
2Employee.prototype = Object.create(Person.prototype)Link prototype chain WITHOUT calling Person()
3Employee.prototype.constructor = EmployeeFix constructor reference (otherwise points to Person)
4Add methods to Employee.prototypeDefine child-specific behavior

❌ Common Mistake: Using new Instead of Object.create

// ❌ WRONG - Calls Person() with no arguments
Employee.prototype = new Person();

// βœ… CORRECT - Creates object with Person.prototype as prototype
Employee.prototype = Object.create(Person.prototype);

5️⃣ ES6 Class Syntax (Syntactic Sugar)

ES6 class is syntactic sugar over prototype-based inheritance:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`Hello, I'm ${this.name}`);
  }
}

class Employee extends Person {
  constructor(name, age, job) {
    super(name, age);  // Calls Person constructor
    this.job = job;
  }

  work() {
    console.log(`${this.name} is working as a ${this.job}`);
  }
}

const emp = new Employee("Daisy", 35, "Designer");
emp.greet();  // Inherited
emp.work();   // Own method

Under the Hood β€” Same Prototype Chain!

// ES6 classes create the SAME prototype chain
console.log(emp.__proto__ === Employee.prototype);  // true
console.log(Employee.prototype.__proto__ === Person.prototype);  // true
console.log(typeof Person);  // "function" - Classes are functions!

6️⃣ Key Methods for Working with Prototypes

MethodPurposeExample
Object.create(proto)Create object with specified prototypeObject.create(Person.prototype)
Object.getPrototypeOf(obj)Get an object's prototypeObject.getPrototypeOf(emp)
Object.setPrototypeOf(obj, proto)Set an object's prototype (slow!)Object.setPrototypeOf(obj, newProto)
obj.hasOwnProperty(prop)Check if property exists on object (not prototype)emp.hasOwnProperty('name')
prop in objCheck if property exists anywhere in chain'greet' in emp
obj instanceof ConstructorCheck if object is instance of constructoremp instanceof Person
const emp = new Employee("Test", 25, "Dev");

// hasOwnProperty vs in
console.log(emp.hasOwnProperty('name'));   // true (own property)
console.log(emp.hasOwnProperty('greet'));  // false (inherited)
console.log('greet' in emp);               // true (found in chain)

// instanceof checks the prototype chain
console.log(emp instanceof Employee);  // true
console.log(emp instanceof Person);    // true
console.log(emp instanceof Object);    // true
console.log(emp instanceof Array);     // false

7️⃣ Method Overriding (Shadowing)

When you define a method on an object or its prototype that already exists higher in the chain:

class Animal {
  speak() {
    console.log("Animal speaks");
  }
}

class Dog extends Animal {
  speak() {
    console.log("Dog barks");
  }

  speakBoth() {
    super.speak();  // Call parent's speak
    this.speak();   // Call own speak
  }
}

const dog = new Dog();
dog.speak();      // "Dog barks" (overridden)
dog.speakBoth();  // "Animal speaks" then "Dog barks"

πŸ” Dry Run: Property Lookup with Shadowing

dog.speak() is called

Step 1: Look for `speak` on dog instance
        -> dog = {} (no own properties)
        -> NOT found

Step 2: Look on Dog.prototype
        -> Dog.prototype = { speak: fn, speakBoth: fn }
        -> FOUND! Execute Dog.prototype.speak()
        -> Output: "Dog barks"

Note: Animal.prototype.speak is never reached
      because Dog.prototype.speak shadows it

8️⃣ Common Interview Questions

Q1: What is the difference between __proto__ and prototype?

Answer:

  • prototype is a property of functions β€” it becomes the prototype of instances created with new
  • __proto__ is a property of all objects β€” it points to the object's actual prototype
function Foo() {}
const obj = new Foo();

console.log(Foo.prototype);       // { constructor: Foo }
console.log(obj.__proto__);       // { constructor: Foo }
console.log(obj.__proto__ === Foo.prototype);  // true

Q2: How do you check if a property is on the object vs the prototype?

Answer:

const obj = { name: "Test" };
Object.prototype.inherited = "I'm inherited";

console.log(obj.hasOwnProperty('name'));      // true
console.log(obj.hasOwnProperty('inherited')); // false
console.log('inherited' in obj);              // true

Q3: What happens if you modify a built-in prototype like Array.prototype?

Answer: It affects ALL arrays in your application (prototype pollution). This is generally discouraged:

// ❌ Dangerous - affects all arrays
Array.prototype.first = function() {
  return this[0];
};

[1, 2, 3].first();  // 1 β€” works but risky

// βœ… Safer - create utility function
const first = (arr) => arr[0];

Q4: Explain instanceof and how it works

Answer: instanceof checks if an object's prototype chain contains Constructor.prototype:

function Person() {}
const p = new Person();

// p instanceof Person checks:
// p.__proto__ === Person.prototype?
// If not, p.__proto__.__proto__ === Person.prototype?
// Continue until null...

console.log(p instanceof Person);  // true
console.log(p instanceof Object);  // true (Object.prototype is in chain)

Q5: What is the output?

function A() {}
function B() {}

A.prototype = B.prototype = {};

const a = new A();
console.log(a instanceof A);  // ?
console.log(a instanceof B);  // ?

Answer: Both are true because a.__proto__ points to the shared {} object, which is both A.prototype and B.prototype.


9️⃣ Common Pitfalls

Pitfall 1: Forgetting to Reset Constructor

function Parent() {}
function Child() {}

Child.prototype = Object.create(Parent.prototype);
// ❌ Child.prototype.constructor is now Parent!

console.log(new Child().constructor);  // Parent

// βœ… Fix: Reset constructor
Child.prototype.constructor = Child;

Pitfall 2: Arrow Functions Don't Have prototype

const Foo = () => {};
console.log(Foo.prototype);  // undefined

// ❌ Can't use as constructor
new Foo();  // TypeError: Foo is not a constructor

Pitfall 3: Modifying Prototype After Creating Instances

function Foo() {}
const obj = new Foo();

// This works - adding to existing prototype
Foo.prototype.greet = function() { console.log("Hi"); };
obj.greet();  // "Hi"

// This breaks existing instances!
Foo.prototype = { newMethod: function() {} };
obj.greet();  // Still "Hi" - obj still linked to OLD prototype

πŸ”Ÿ Summary

ConceptDescription
PrototypeAn object from which other objects inherit properties
prototypeProperty of functions; becomes __proto__ of instances
__proto__Internal link to an object's prototype
Prototype ChainThe chain of prototypes JavaScript searches for properties
Object.create()Create object with specified prototype
ES6 ClassesSyntactic sugar over prototype inheritance

Key Takeaways

  1. Every object has a prototype (except Object.prototype.__proto__ which is null)
  2. Methods on prototype are shared β€” memory efficient
  3. Property lookup walks the chain β€” own properties checked first
  4. class is syntactic sugar β€” same prototype mechanism underneath
  5. Use Object.create() for inheritance β€” not new Parent()

πŸ“š Further Reading

  • MDN: Inheritance and the prototype chain
  • JavaScript.info: Prototypes

Quick Quiz

Test your understanding with 3 quick questions

Q1What is the difference between `__proto__` and `prototype`?
Q2What happens when you access a property that doesn't exist on an object?
Q3Why should you use `Object.create(Parent.prototype)` instead of `new Parent()` when setting up inheritance?

Continue Reading

CrackFrontend

Your guide to mastering frontend interviews

Resources

LibraryPracticeDonate

Company

About UsContact

Legal

Privacy PolicyTerms of Service

Built with ❀️ by Tushar Khanna