What is stored in __proto__
__proto__ is an internal property of an object that stores a reference to its prototype, that is, to the object it inherits properties and methods from. In other words, it is the access point, visible from ordinary JavaScript code, to the internal [[Prototype]] slot, which you can both read and reassign.
Theory
TL;DR
__proto__holds the object that acts as the current object's prototype, ornull.- This is the link the engine follows when it cannot find a property on the object itself.
- An object's
__proto__points to theprototypeof the function that created it. __proto__andprototypeare different things: the first lives on objects, the second on constructor functions.- The official equivalents are
Object.getPrototypeOf()andObject.setPrototypeOf(). Object.prototype.__proto__isnull, which marks the end of the chain.
Quick example
const animal = { eats: true };
const dog = { barks: true };
dog.__proto__ = animal; // set animal as the prototype of dog
console.log(dog.eats); // true, inherited from animal
console.log(dog.barks); // true, an own propertyWhat happens here:
doghas noeatsproperty of its own;- JavaScript looks it up in
dog.__proto__, that is, inanimal; - it finds it and returns
true.
What exactly is stored in __proto__
__proto__ stores an object that serves as the prototype of the current object.
const user = { name: 'Alice' };
console.log(user.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null, the end of the chainSo the chain is:
user -> Object.prototype -> nullWhat the chain looks like for an array
const arr = [1, 2, 3];
console.log(arr.__proto__ === Array.prototype); // true
console.log(arr.__proto__.__proto__ === Object.prototype); // true
console.log(arr.__proto__.__proto__.__proto__); // nullFor an array the chain looks like this:
arr -> Array.prototype -> Object.prototype -> nullThat is exactly why an array has both map() from Array.prototype and hasOwnProperty() from Object.prototype.
__proto__ is not the same as prototype
This is the most common confusion in interviews.
| Property | Where it lives | What it does |
|---|---|---|
__proto__ | on an object | a reference to that object's prototype |
prototype | on a constructor function | the template for future objects, that is, their prototype |
function User() {}
const alice = new User();
console.log(alice.__proto__ === User.prototype); // true
console.log(User.prototype.constructor === User); // trueSo an object's __proto__ points to the prototype of the function that created it.
How to work with prototypes safely
The modern equivalents, which are preferable to __proto__:
// Read the prototype
Object.getPrototypeOf(obj);
// Set the prototype
Object.setPrototypeOf(obj, proto);Historically __proto__ was an informal engine extension, and only later was it standardised as a legacy compatibility feature. The methods above, by contrast, are an official part of the language.
Checking that both ways give the same result:
const animal = { eats: true };
const dog = Object.create(animal);
console.log(Object.getPrototypeOf(dog) === animal); // true
console.log(dog.__proto__ === animal); // trueWhy using __proto__ directly is discouraged
- It is a legacy mechanism, kept in the standard only for web compatibility.
- Assigning to
__proto__is slow: it invalidates the engine's internal optimisations for that object. - It is easy to break the prototype chain by accident and lose the standard methods.
- An object created with
Object.create(null)does not have this accessor at all, because it does not inherit fromObject.prototype.
Use these instead:
Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, newProto);Better still, set the prototype at creation time with Object.create(proto) or with class.
Summary
| Property | What it stores | Where it is used | Modern alternative |
|---|---|---|---|
__proto__ | a reference to the object's prototype | on every object | Object.getPrototypeOf(), Object.setPrototypeOf() |
prototype | the prototype that new objects receive when created with new | on constructor functions | none, it is a separate mechanism |
Common mistakes
- Saying that functions have
__proto__instead ofprototype. A function has both, and they mean different things: a function's__proto__points toFunction.prototype. - Reassigning
__proto__in a loop or in hot code. It is the slowest prototype operation there is. - Thinking
__proto__copies properties. It only stores a reference, the properties stay on the prototype. - Accepting an external
__proto__key without validation. A naive merge of JSON from an outside API can replace the prototype, which is the classic prototype pollution vulnerability. - Expecting
__proto__on an object without a prototype. ForObject.create(null)the access returnsundefined, like any missing property.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.