We can do console.log(Object.prototype) → and it shows the properties and methods that all objects inherit.But try console.log (Object.__proto__
) → it gives ƒ () { [native code] }.
Ever wondered why?
Because our initial object is created using a constructor.
And only in constructors we can add properties by using prototype
.
Now, who inherits?
It’s like our global Object
constructor. The objects created from it inherit through prototype
.
That prototype
itself has inner things we use—like .create()
and .__proto__
.
All these are functions living on Object.prototype
.
lets deep dive
1 — Quick overview
Every object in JavaScript has a hidden pointer to another object (its prototype). When you ask for a property, JS checks the object first, then follows that pointer up the chain until it finds the property or reaches null
.
2 — Object.create(proto)
example (start here)
const parent = {
greet() { console.log("Hello from parent!"); }
};
const child = Object.create(parent);
console.log(child); // shows child as {}
console.log(child.__proto__); // shows the parent object in console
child.greet(); // "Hello from parent!"
What happened (step by step):
-
child
is created as an empty object. - Internally, JS sets
child
’s hidden slot[[Prototype]]
to point toparent
. (DevTools shows this aschild.__proto__
.) - When you call
child.greet()
, JS doesn’t findgreet
onchild
, so it looks atchild.__proto__
(theparent
) and findsgreet
there.
ASCII view:
child {}
__proto__ → parent { greet: f }
__proto__ → Object.prototype
__proto__ → null
3 — Understanding the console output: { greet: ƒ } [[Prototype]]: Object
When the console shows:
{ greet: ƒ }
[[Prototype]]: Object
-
{ greet: ƒ }
= theparent
object (it has agreet
function). -
[[Prototype]]: Object
= meaning theparent
object itself has a prototype, which isObject.prototype
. - The double brackets
[[Prototype]]
mean this is an internal slot (not a normal enumerable property).
Simple sentence: the console is telling you the parent
has its own parent — Object.prototype
.
4 — __proto__
vs prototype
(exact difference)
-
__proto__
- Exists on objects.
- It’s the actual reference (internal slot) to the parent object.
- You can inspect it with
obj.__proto__
orObject.getPrototypeOf(obj)
.
-
prototype
- Exists on constructor functions (e.g.,
function Person(){}
→Person.prototype
). - It is the object that will become the
__proto__
of instances created by that constructor.
- Exists on constructor functions (e.g.,
Proof code:
function Person(){ }
const p = new Person();
console.log(p.__proto__ === Person.prototype); // true
5 — What new
does (exact, ordered steps)
When you run const x = new C(args)
:
- Create a new empty object:
{}
. - Set the object’s internal
[[Prototype]]
toC.prototype
. - Call
C
withthis
set to that new object, filling properties onthis
. - Return the new object (unless constructor explicitly returns another object).
Visual:
x { own properties }
__proto__ → C.prototype { shared methods }
__proto__ → Object.prototype
__proto__ → null
6 — Property lookup algorithm (how JS finds a property)
When you do obj.someProp
:
- Check
obj
’s own properties. If found → return it. - Else, set
obj = obj.__proto__
and repeat step 1. - Continue until
obj
becomesnull
. If not found →undefined
.
This is why child.greet()
works even though greet
is not on child
: the lookup finds greet
on parent
.
7 — Where to put data vs methods (practical rule)
- Put per-object data inside the constructor (each instance gets its own copy).
function Person(name){ this.name = name; }
- Put shared methods on the constructor’s
prototype
(all instances reuse the same function).
Person.prototype.sayHi = function(){ console.log(this.name); }
Why: methods on prototype
save memory and make behavior consistent for all instances.
8 — The top of the chain: Object.prototype
→ null
- Most objects eventually point to
Object.prototype
. -
Object.prototype.__proto__
isnull
. Thatnull
is the end — no more lookup beyond that.
Example check:
console.log(Object.getPrototypeOf({}) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype)); // null
9 — Function vs Object (short note)
-
Object
itself is a function (typeof Object === 'function'
). - Functions are objects too: they have their own
__proto__
(usuallyFunction.prototype
). - So constructors and built-ins follow the same prototype rules (they are objects that link to prototypes).
10 — How to inspect safely (recommended tools)
-
Object.getPrototypeOf(obj)
→ preferred way to get prototype (safer than__proto__
). -
obj.hasOwnProperty('x')
→ checks own properties only. -
console.log(obj.__proto__)
or expand object in DevTools → shows[[Prototype]]
.
11 — Common mistakes & best practices
-
Don’t rely on
__proto__
for setting prototypes in production (it’s slower). UseObject.create(proto)
orObject.setPrototypeOf()
only when needed. -
Don’t mutate shared prototype state carelessly — changing
PrototypeObject.sharedArray.push(...)
affects all instances. - Use
prototype
for methods, constructor for instance data.
12 — Short cheat-sheet (memorize this)
-
Object.create(proto)
→ create object whose__proto__
isproto
. -
__proto__
→ object’s hidden parent pointer. -
prototype
→ constructor’s blueprint object. -
new
→ links instance__proto__
to constructor’sprototype
, then runs constructor. -
Object.prototype.__proto__ === null
→ chain end.
Top comments (0)