prototype is a property on constructor functions that becomes the [[Prototype]] of instances created with new. __proto__ is the (legacy) accessor for an object's [[Prototype]] link used for property lookup. Mastering this distinction explains inheritance, the prototype chain, and why obj.__proto__ === Foo.prototype after new Foo().
prototype vs __proto__ in JavaScript (Prototype Chain, new, and Object.getPrototypeOf)
Use guided tracks for structured prep, then practice company-specific question sets when you want targeted interview coverage.
High-signal answer (what interviewers want)
prototypeis a property on functions (constructors). It’s the object that instances created withnewwill delegate to.__proto__is the legacy accessor for an object’s internal[[Prototype]]link (the real prototype chain pointer).
They connect via new: Object.getPrototypeOf(obj) === Foo.prototype.
Name | Belongs to | Meaning | Use in practice |
|---|---|---|---|
| Constructor function | The object used as the prototype for instances created by | Put shared methods here (or use |
| Any object | The actual prototype link used during property lookup | Prefer |
The bridge: what new does
When you run:
const obj = new Foo()
JavaScript (roughly) does:
1) Create a new empty object
2) Set its
[[Prototype]] to Foo.prototype3) Call
Foo with this = objThat step #2 is why the two terms show up together in explanations.
function Foo() {}
Foo.prototype.sayHi = function () { return 'hi'; };
const obj = new Foo();
obj.sayHi(); // 'hi'
// Canonical checks (prefer these):
Object.getPrototypeOf(obj) === Foo.prototype; // true
// Legacy accessor (works, but prefer getPrototypeOf):
obj.__proto__ === Foo.prototype; // true
Prototype chain property lookup
When you read obj.prop, the engine:
1) Looks on obj itself
2) If not found, follows [[Prototype]] to the next object
3) Repeats until it finds the property or hits null
That chain is the prototype chain.
const base = { x: 1 };
const obj = Object.create(base);
obj.x; // 1 (found on base via prototype chain)
obj.hasOwnProperty('x'); // false (x is inherited)
Object.getPrototypeOf(obj) === base; // true
Top interview pitfalls
1) Mixing them up
prototypeis on the constructor (Foo.prototype)__proto__/[[Prototype]]is on the instance (obj)
2) Thinking __proto__ is the “official” API
Use:
Object.getPrototypeOf(obj)Object.setPrototypeOf(obj, proto)
3) Forgetting functions are objects
Functions have [[Prototype]] too (so Foo.__proto__ exists), and also have Foo.prototype (used for instances).
Mind-bender (explains most diagrams)
function A() {}
const a = new A();
// Instance delegates to A.prototype:
Object.getPrototypeOf(a) === A.prototype; // true
// A is a function object, so it delegates to Function.prototype:
Object.getPrototypeOf(A) === Function.prototype; // true
// A.prototype is a normal object, so it delegates to Object.prototype:
Object.getPrototypeOf(A.prototype) === Object.prototype; // true
// End of the chain:
Object.getPrototypeOf(Object.prototype) === null; // true
Practical rule
- Put shared methods on
Foo.prototype(or useclass Foo {}). - Inspect prototypes with
Object.getPrototypeOf. - Avoid setting prototypes at runtime unless you must (can be slow and confusing).
One-sentence answer
Foo.prototype is the object that instances created with new Foo() will inherit from, while obj.__proto__ (aka [[Prototype]]) is the actual internal prototype link on obj used for property lookup.