Mastering JavaScript Prototypes: Unraveling __proto__ and prototype


🔰Introduction
JavaScript’s object system is often misunderstood, especially when it comes to inheritance. Unlike class-based languages, JavaScript uses prototypes to link objects and share properties efficiently. At the core of this mechanism are __proto__
and prototype
, two fundamental concepts that define how objects inherit behaviors in JavaScript.
Understanding these concepts is crucial for writing optimized, maintainable, and scalable JavaScript code. Whether you're a beginner looking to grasp the basics or an experienced developer aiming to solidify your understanding, this guide will walk you through:
✅ What is __proto__
? The internal reference that links an object to its prototype.
✅ How does the prototype chain work? The step-by-step lookup process for inherited properties.
✅ What is prototype
? The blueprint for defining shared methods in constructor functions.
✅ Key differences between __proto__
and prototype
to clear up common misconceptions.
By the end of this article, you'll have a clear, practical understanding of how JavaScript handles inheritance under the hood. 🚀
Let’s dive in! 🔥Demystifying __proto__
and Prototype in JavaScript: A Comprehensive Guide to Object Inheritance, Prototype Chaining, and How JavaScript Shares Behavior
🔰Understanding __proto__
and prototype
Imagine you are part of a family. You inherit certain traits from your parents, like eye color or hair type. Now, your parents inherited their traits from your grandparents, and so on. This chain of inheritance continues up the family tree.
In JavaScript, objects work the same way! Instead of inheriting physical traits, they inherit properties and methods from other objects through a mechanism called prototype chaining.
For example:
If you don’t know how to drive but your parent does, you can "borrow" that skill from them.
If your parent doesn’t know but your grandparent does, you inherit from them instead.
This continues until you reach the top-most ancestor.
In JavaScript, the parent of an object is its prototype, and __proto__
is the link that connects an object to its prototype.
💡 In simple terms: If JavaScript doesn’t find a property on an object, it looks at its prototype (parent). If it’s not found there, it looks at the prototype’s prototype (grandparent), and this continues until it reaches null
, which is the root ancestor.
With this analogy, let’s now explore how JavaScript implements this inheritance using __proto__
and prototype chaining! 🚀
❇️ What is __proto__
?
__proto__
is an internal property in JavaScript that links an object to its prototype. It allows objects to inherit properties and methods from other objects via prototype chaining.
__proto__
is a property, not a keyword, function, or method. It is an internal reference that links an object to its in-built prototype.
🔹 Prototype Chain & Inheritance
Every JavaScript object has a prototype from which it can inherit properties. When accessing a property or method on an object, JavaScript first looks for it on the object itself. If not found, it checks the object's prototype, then the prototype's prototype, and so on until it reaches null
. This is called prototype chaining.
🔹 Example:
const person = {
greet: function() {
console.log("Hello!");
}
};
const user = {
name: "Anushka"
};
user.__proto__ = person; // Setting person as the prototype of user
console.log(user.name); // Alice (from user)
user.greet(); // Hello! (inherited from person)
🔹 How Prototype Chain Works
console.log(user.__proto__); // Points to 'person'
console.log(user.__proto__.__proto__); // Points to Object.prototype
console.log(user.__proto__.__proto__.__proto__); // null (end of the chain)
🔹Prototype Chain Diagram
child → parent → grandparent → Object.prototype → null
__proto__
was not originally part of the ECMAScript standard, but browsers implemented it for debugging.It is now standardized in ECMAScript 2015 (ES6) but mainly for legacy compatibility.
Modern JavaScript prefers
Object.getPrototypeOf(obj)
andObject.setPrototypeOf(obj)
instead.
❇️ Now, What is prototype
in JavaScript?
The prototype
in JavaScript is an object that is associated with a constructor function and is used to define properties and methods that should be shared by all instances created from that constructor.
A constructor function is just a regular function that is used to create multiple objects with the same structure. It acts like a blueprint for objects. Although it is an old way to do that.
Here is an example
function Person(name, age) {
this.name = name;
this.age = age;
}
👉 Person
is a constructor function.
👉 When you call new Person("John", 30)
, it creates a new object with name
and age
properties.
💡Key Facts About prototype
:
prototype
is an object that belongs to functions and is used to define shared properties/methods.Objects created using a constructor function inherit from that function’s
prototype
.Not every object has a
prototype
, but every function has aprototype
property.
🔷 Understanding prototype
with an Example
function Animal(name) {
this.name = name;
}
// Adding a method to the prototype of Animal object
Animal.prototype.speak = function() {
console.log(`${this.name} makes a sound`);
};
// Creating instances
const dog = new Animal("Dog");
const cat = new Animal("Cat");
dog.speak(); // Output: Dog makes a sound
cat.speak(); // Output: Cat makes a sound
🔷 Flow of the above Code segment
The function
Animal
has aprototype
object.When
new Animal("Dog")
is executed:A new object is created.
This object’s
__proto__
is set toAnimal.prototype
.
When
dog.speak()
is called:JavaScript first looks for
speak
insidedog
.If not found, it checks
dog.__proto__
(which isAnimal.prototype
).It finds
speak
there and executes it.
🔷 How prototype
Works Internally
Every function (that is not an arrow function) in JavaScript automatically gets a prototype
property, which is an object.
function Example() {} console.log(typeof Example.prototype); // "object" console.log(Example.prototype); // { constructor: Example }
By default,
Example.prototype
contains:{ constructor: Example }
You can add methods and properties to this
prototype
object.
🔷 Fundamental Difference b/w proto and prototype
Feature | __proto__ | prototype |
What it is | A reference (pointer) to the prototype of an object | A property of constructor functions that defines the prototype of objects created from it |
Belongs to | Every object in JavaScript | Only functions (specifically constructor functions) |
Type | Object | Object |
Purpose | Links an object to its prototype | Defines methods and properties shared across all instances created by a constructor function |
Used by | Instances (objects) | Constructor functions |
Accessed via | obj.__proto__ or Object.getPrototypeOf(obj) | ConstructorFunction.prototype |
Modifiable? | Yes, but modifying it is not recommended | Yes, used to define shared behavior |
🔹prototype
is a Property of Constructor Functions
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() {
console.log(`Hello, I am ${this.name}`);
};
Person.prototype
is an object that containssayHello
.Any object created using
new Person()
will inherit fromPerson.prototype
.
🔹__proto__
is a Hidden Property in Instances
const john = new Person("John");
console.log(john.__proto__ === Person.prototype); //Output: true
console.log(Object.getPrototypeOf(john) === Person.prototype); //Output: true
john.__proto__
points toPerson.prototype
, meaningjohn
inherits properties from it.The
prototype
object ofPerson
becomes the__proto__
of instances created bynew Person()
.
🔹Conceptual View
john ---> Person.prototype ---> Object.prototype ---> null
john.__proto__
→ Points toPerson.prototype
Person.prototype.__proto__
→ Points toObject.prototype
Object.prototype.__proto__
→null
(end of prototype chain)
One Line Summary
proto
, which links it to the prototype object of its constructor function. The constructor function itself has a prototype
property, which defines shared methods. This mechanism allows objects to inherit properties and methods, forming a prototype chain."🔰One Shot Summary
🔷 Fundamental Relationships
Every JavaScript object has an internal link (
__proto__
) to its prototype.A function (constructor) has a
prototype
object that is inherited by all instances created from it.__proto__
is an object's reference to its prototype, whileprototype
is a property of constructor functions.
🔷 How They Are Connected
Think of it like a chain:
Every object in JavaScript has an internal property called
__proto__
.This
__proto__
points to the prototype object of the constructor function that created it.The constructor function itself has a special
prototype
property, which is an object that holds shared methods and properties.This process forms the Prototype Chain, which allows inheritance in JavaScript.
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, I am ${this.name}`);
};
const virat = new Person("Virat");
console.log(virat.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
Step 1: virat.__proto__ === Person.prototype
👉 virat
is an instance of Person
created using new Person()
.
👉 Every object created by a constructor function gets its __proto__
set to the constructor’s prototype
.
🔹 Conclusion: virat.__proto__
and Person.prototype
are the same.
Step 2: Person.prototype.__proto__ === Object.prototype
👉 Person.prototype
itself is an object.
👉 All objects in JavaScript (except null
) inherit from Object.prototype
.
🔹 Conclusion: Person.prototype.__proto__
points to Object.prototype
, showing that custom objects ultimately inherit from JavaScript's built-in Object
.
Step 3: Object.prototype.__proto__ === null
👉 Object.prototype
is the top-most prototype in JavaScript.
👉 It has no prototype above it, so its __proto__
is null
.
🔹 Conclusion: The prototype chain ends at null
, confirming that there’s no prototype beyond Object.prototype
.
🎉 Congratulations! 🎉
You've made it this far, and that means you’ve unlocked a solid understanding of JavaScript’s prototype chain! 🚀
I hope that after all these discussions, you now feel confident about how objects, prototypes, __proto__
, and constructor functions work together under the hood.
But learning never stops! Do you feel like you’ve grasped the concept? Or do you have any lingering doubts? 🤔
Drop your thoughts in the comments—I’d love to hear your take! 💬👇
🔴 But Wait… Is This Approach Perfect?
While prototype-based inheritance is powerful, it comes with a few drawbacks:
1️⃣ Complex Syntax & Readability Issues
The
prototype
and__proto__
chain can be confusing for beginners.Manually setting prototypes (
obj.__proto__ = anotherObj
) is not intuitive.
2️⃣ Inheritance is Not Explicit
Unlike other languages that use
class
, JavaScript’s prototype-based inheritance is implicit.Understanding how properties/methods are inherited requires tracing through multiple prototype levels.
3️⃣ Modifying __proto__
Directly is Bad Practice
Changing
__proto__
directly is slow and discouraged because it impacts performance.Instead, Object.create() should be used to set prototypes.
4️⃣ Boilerplate Code for Constructor Functions
Defining constructor functions and manually attaching methods to
prototype
takes extra lines of code.There’s no built-in
super
keyword like in ES6 classes.
💡 This is where modern JavaScript solutions come in!
To make things cleaner, ES6 introduced class
syntax, which simplifies inheritance while keeping the power of prototypes.
🔜 What’s Next?
In the next blog, we’ll explore:
✔️ How class
simplifies prototype-based inheritance
✔️ Using Object.create()
for prototype-based inheritance without constructor functions
✔️ How extends
and super
improve inheritance structure
👉 Next up: "Modern JavaScript Inheritance: Classes, Object.create(), and More!"
Stay tuned! 🚀
Subscribe to my newsletter
Read articles from Santwan Pathak directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Santwan Pathak
Santwan Pathak
"A beginner in tech with big aspirations. Passionate about web development, AI, and creating impactful solutions. Always learning, always growing."