Skip to main content

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, or null.
  • This is the link the engine follows when it cannot find a property on the object itself.
  • An object's __proto__ points to the prototype of the function that created it.
  • __proto__ and prototype are different things: the first lives on objects, the second on constructor functions.
  • The official equivalents are Object.getPrototypeOf() and Object.setPrototypeOf().
  • Object.prototype.__proto__ is null, which marks the end of the chain.

Quick example

javascript
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 property

What happens here:

  • dog has no eats property of its own;
  • JavaScript looks it up in dog.__proto__, that is, in animal;
  • 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.

javascript
const user = { name: 'Alice' }; console.log(user.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__); // null, the end of the chain

So the chain is:

text
user -> Object.prototype -> null

What the chain looks like for an array

javascript
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__); // null

For an array the chain looks like this:

text
arr -> Array.prototype -> Object.prototype -> null

That 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.

PropertyWhere it livesWhat it does
__proto__on an objecta reference to that object's prototype
prototypeon a constructor functionthe template for future objects, that is, their prototype
javascript
function User() {} const alice = new User(); console.log(alice.__proto__ === User.prototype); // true console.log(User.prototype.constructor === User); // true

So 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__:

javascript
// 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:

javascript
const animal = { eats: true }; const dog = Object.create(animal); console.log(Object.getPrototypeOf(dog) === animal); // true console.log(dog.__proto__ === animal); // true

Why 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 from Object.prototype.

Use these instead:

javascript
Object.getPrototypeOf(obj); Object.setPrototypeOf(obj, newProto);

Better still, set the prototype at creation time with Object.create(proto) or with class.

Summary

PropertyWhat it storesWhere it is usedModern alternative
__proto__a reference to the object's prototypeon every objectObject.getPrototypeOf(), Object.setPrototypeOf()
prototypethe prototype that new objects receive when created with newon constructor functionsnone, it is a separate mechanism

Common mistakes

  • Saying that functions have __proto__ instead of prototype. A function has both, and they mean different things: a function's __proto__ points to Function.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. For Object.create(null) the access returns undefined, like any missing property.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.