Prototypal Inheritance in JavaScript: An
In-Depth Interview Guide
Author: Manus AI Date: December 3, 2025
Introduction: Understanding JavaScript’s Core
Inheritance Model
JavaScript is a prototype-based language, meaning that its inheritance mechanism is
fundamentally different from the class-based inheritance found in languages like Java
or C++ [1]. Instead of inheriting from a class blueprint, objects in JavaScript inherit
properties and methods directly from other objects, which are referred to as their
prototypes. This mechanism is known as prototypal inheritance.
The concept is foundational to JavaScript and is a frequent topic in technical
interviews, as it tests a candidate’s deep understanding of the language’s object
model.
The Prototype Chain
When attempting to access a property or method on an object, JavaScript first checks
if the property exists directly on the object itself. If it does not, the search continues up
the object’s internal link to its prototype. This process repeats, forming a sequence of
linked objects called the prototype chain [1].
The chain continues until one of two things happens:
1. The property or method is found on one of the prototype objects.
2. The end of the chain is reached, which is always an object whose prototype is
null . By definition, null has no prototype, and the search terminates, resulting
in undefined .
This dynamic lookup process is what enables property and method sharing among
objects.
Code Example: The Prototype Chain in Action
// 1. Define a prototype object
const animal = {
eats: true,
walk() {
[Link]("Animal walks.");
}
};
// 2. Create a new object and set its prototype to 'animal'
const rabbit = {
jumps: true,
__proto__: animal // Modern equivalent: [Link](rabbit,
animal)
};
// 3. Accessing properties:
[Link]([Link]); // true (Found directly on 'rabbit')
[Link]([Link]); // true (Found on 'animal' via the prototype
chain)
[Link](); // "Animal walks." (Method found on 'animal')
// 4. The end of the chain:
[Link]([Link](animal) === [Link]); // true
[Link]([Link]([Link])); // null
The Three Pillars: [[Prototype]] , .prototype , and
.__proto__
A common source of confusion, and a critical interview question, is the distinction
between the three terms used to describe prototypes.
Term Type Description Access Method
The actual, internal link that
forms the prototype chain.
Internal
[[Prototype]] Every object has this slot, [Link](obj)
Slot
which points to its prototype
object.
A property that exists only
on constructor functions and
classes. It is the object that
Property
will be set as the
.prototype of a [Link]
[[Prototype]] of all
Function
instances created with that
constructor using the new
keyword.
A deprecated, non-standard
(but widely supported)
getter/setter that exposes
the internal [[Prototype]]
Accessor slot. It should be avoided in
.__proto__ instance.__proto__
Property favor of
[Link]()
and
[Link]()
[4].
Code Example: Distinguishing the Terms
// 1. Constructor Function
function Person(name) {
[Link] = name;
}
// 2. .prototype: Exists on the constructor function
[Link] = function() {
[Link](`Hello, my name is ${[Link]}`);
};
// 3. Create an instance
const john = new Person("John");
// 4. [[Prototype]] and .__proto__: Exists on the instance
// The instance's internal [[Prototype]] is set to the constructor's
.prototype
[Link]([Link](john) === [Link]); // true
[Link](john.__proto__ === [Link]); // true (Avoid
using __proto__)
// 5. The constructor function itself does not have a [[Prototype]] link to
its own .prototype
[Link]([Link] === john.__proto__); // true
Modern Prototype Management
While constructor functions and the new keyword are one way to manage prototypes,
modern JavaScript provides explicit methods for creating and manipulating the
prototype chain, which are preferred for their clarity and performance.
1. [Link](proto, [propertiesObject])
This method creates a new object and explicitly sets its [[Prototype]] to the
specified proto object [3]. This is the most direct way to implement prototypal
inheritance without using constructor functions.
const carPrototype = {
drive() {
[Link](`Driving a ${[Link]}`);
}
};
// Create a new object 'myCar' with 'carPrototype' as its prototype
const myCar = [Link](carPrototype, {
make: { value: "Tesla", enumerable: true }
});
[Link](); // Output: Driving a Tesla
[Link]([Link](myCar) === carPrototype); // true
2. [Link](obj)
This is the standard, reliable way to retrieve the value of an object’s internal
[[Prototype]] slot [2].
const obj = {};
const proto = [Link](obj);
[Link](proto === [Link]); // true
3. [Link](obj, proto)
This method allows you to change the prototype of an object after it has been created.
While powerful, it is generally discouraged for performance reasons, as it can cause de-
optimization in JavaScript engines [2].
const dog = { bark: () => [Link]("Woof!") };
const robot = { model: "T-800" };
// Change robot's prototype to dog
[Link](robot, dog);
[Link](); // Output: Woof!
ES6 Classes: Syntactic Sugar Over Prototypes
The introduction of the class keyword in ECMAScript 2015 (ES6) provided a cleaner,
more familiar syntax for object-oriented programming, but it does not introduce a
new inheritance model [1]. ES6 classes are merely syntactic sugar over the existing
prototypal inheritance mechanism.
When you define a class and use the extends keyword, JavaScript is simply setting up
the prototype chain under the hood using the same [[Prototype]] links.
Class Syntax vs. Prototypal Mechanism
Class Syntax Underlying Prototypal Mechanism
class Animal { ... } A constructor function Animal is created.
A new object is created, and its [[Prototype]] is set to
new Animal()
[Link] .
class Dog extends Animal The [Link] object’s [[Prototype]] is set to
{ ... } [Link] .
Methods defined in the class Methods are added to the class’s .prototype object.
Understanding this relationship is key to demonstrating deep knowledge in an
interview. The interviewer wants to know that you understand the “magic” behind
the class keyword.
Conclusion: Key Takeaways for the Interview
To excel in the interview, focus on these core points:
Prototypal Inheritance is the mechanism where objects inherit from other
objects.
The Prototype Chain is the dynamic lookup path for properties and methods.
[[Prototype]] is the internal link; .prototype is a property on constructor
functions; .__proto__ is the deprecated accessor for the internal link.
[Link]() is the preferred modern way to establish inheritance.
ES6 Classes are syntactic sugar that simplify the setup of the prototype chain.
References
[1] Inheritance and the prototype chain - JavaScript | MDN [2] [Link]() -
JavaScript | MDN [3] [Link]() - JavaScript | MDN [4] Difference between proto
and prototype - GeeksforGeeks