[[Prototype]] vs __proto__ vs .prototype in Javascript
π― The Three Concepts
1οΈβ£ [[Prototype]] (Internal Prototype)
What:
Hidden internal property inside every JavaScript object
Purpose:
The actual mechanism JS uses for inheritance and property lookup
Access:
Cannot access directly in code
obj.[[Prototype]]// β Syntax errorThink of it as:
The real inheritance link
2οΈβ£ __proto__ (Proto Accessor)
What:
Getter/setter property that exposes [[Prototype]]
Where:
Available on all objects (via Object.prototype)
Status:
β οΈ Deprecated (but widely supported)
obj.__proto__ ===Object.getPrototypeOf(obj)// β
trueβ Modern alternatives (use these instead):
Object.getPrototypeOf(obj)// Get prototype
Object.setPrototypeOf(obj, proto)// Set prototype
Object.create(proto)// Create with prototypeThink of it as:
Legacy way to view/change [[Prototype]]
3οΈβ£ .prototype (Prototype Property)
What:
Regular object property that exists only on functions
Purpose:
Blueprint object used when function is called with new
Key point:
NOT the functionβs own prototype
functionUser() {}
User.prototype// β
exists (it's an object)const u =newUser();
u.prototype// β undefined (instances don't have it)Think of it as:
Get Aditya Patelβs stories inΒ yourΒ inbox
Join Medium for free to get updates fromΒ thisΒ writer.
Template for future instances
π How They Connect: The new Operator
functionUser(name) {
this.name = name;
}const u1 =newUser('Alice');What new does internally:
// Simplified version
1.Create emptyobject:const u1 = {}
2.Linkprototype: u1.[[Prototype]] =User.prototype
3.Callconstructor:User.call(u1,'Alice')
4.Returnobject:return u1The connection:
u1.__proto__ === User.prototype // β
trueπ₯ Multiple Instances Share One Prototype
functionUser() {}
User.prototype.sayHi =function() {
console.log('Hi!');
};const u1 =newUser();
const u2 =newUser();
const u3 =newUser();Memory structure:
u1.__proto__ βββ
u2.__proto__ βββΌβββ User.prototype (ONE object in memory)
u3.__proto__ ββββ Benefits:
- Methods defined once
- Shared across all instances
- Memory efficient
π Prototype Lookup Chain
const u1 =newUser();
u1.sayHi();// How does JS find this?Lookup order:
- Check
u1itself β Not found - Check
u1.[[Prototype]](i.e.,User.prototype) β Found! β - If not found, check
User.prototype.[[Prototype]]βObject.prototype - If still not found, check
Object.prototype.[[Prototype]]βnull
π Function vs Object
Function (Constructor)
functionUser() {}Has:
- β
.prototype(points to object for instances) - β
__proto__(points toFunction.prototype) - β
[[Prototype]](internal, =Function.prototype)
Why?
Functions can create objects AND are objects themselves.
Regular Object (Instance)
const obj = {};Has:
- β
.prototype(doesn't exist) - β
__proto__(points toObject.prototype) - β
[[Prototype]](internal, =Object.prototype)
Why?
Objects are instances, not constructors.
π Classes = Syntactic Sugar
classUser {
sayHi() {
console.log('Hi');
}
}Behind the scenes:
// Equivalent to:
functionUser() {}
User.prototype.sayHi =function() {
console.log('Hi');
};π Classes use the same prototype system internally!
π The Complete Picture
βββββββββββββββββββββββββββββββββββββββ
βUser (function) β
β .prototype ββββββββββββ β
β __proto__ βFunction.prototype β
βββββββββββββββββββββββββββΌββββββββββββ
β
β
βββββββββββββββββββββββββ
βUser.prototype β
β (object) β
β -sayHi() β
βββββββββββββ¬ββββββββββββ
β
βββββββββββββββββΌββββββββββββββββ
β β β
βββββββ΄ββββββ βββββββ΄ββββββ βββββββ΄ββββββ
β u1 β β u2 β β u3 β
β __proto__ β β __proto__ β β __proto__ β
βββββββββββββ βββββββββββββ βββββββββββββπ Golden Rules (Memorize These!)
.prototypeβ Property on constructor functions only__proto__β Accessor on all objects (deprecated, useObject.getPrototypeOf())[[Prototype]]β Internal link used by JS engine- All instances share the same prototype object
- Property lookup travels up the prototype chain
π‘ Interview One-Liner
[[Prototype]] is the actual inheritance mechanism, __proto__ is a deprecated way to access it, and .prototype is the object that constructor functions give to their instances as their [[Prototype]].
β οΈ Common Mistakes
β Wrong:
functionUser() {}
const u =newUser();
u.prototype.sayHi =function() {}// Error! u.prototype is undefinedβ Correct:
User.prototype.sayHi =function() {}// Add to constructor's prototypeπ Quick Reference
Concept Location Purpose Access [[Prototype]] All objects Internal inheritance link Object.getPrototypeOf() __proto__ All objects Legacy accessor Direct (deprecated) .prototype Functions only Template for instances Direct



