In Google Chrom's javascript, objects have a property named __proto__
that points to their prototype (or parent) object.
var foo = {};
console.log(foo.__proto__ === Object.prototype); //returns true
However, this is not true for the Object
object.
console.log(Object.__proto__ === Object.prototype); //returns false
The Object.__proto__
property appears to be an empty method
> console.log(Object.__proto__.toString());
function () {}
Beyond serving as a warning story about relying on javascript features that start outside standard bodies -- what is the Object.__proto__
function?
Based on squint's comments above, I've been able to get to the bottom of this. My unstated, incorrect (and 10+ year) assumption was that the global
Object
helper object's prototype object was also the top level "prototype of prototypes" at the top/end of javascript's prototype chain. This is not true.The
Object
helper object and theFunction
helper object both have the same parent prototype-objectSo, the reason
Object.__proto__
points to an empty function is -- that empty function is its prototype object for theObject
object. If you want to get to the prototype of prototypes fromObject
(without using.prototype
), you need to dig back a bit further.I also put together a quick diagram that maps out the real prototypes of a few of Javascript's lower level helper/constructor objects.
Finally -- I also also discovered Google Chrome has implemented the
Reflect
object, which includes agetPrototypeOf
method, which appears to be the same as theObject.getPrototypeOf
method.The top of the object graph is formed to maintain as much consistency with the expectations set elsewhere in the spec.
Necessarily, there comes a point where normal object linkages cannot be used because you "run out of objects".
A basic understanding of JavaScript leads us to expect the
[[Prototype]]
ofObject
to be the prototype property of the function used to create theObject
function-object.We expect
Function
s to be created using theFunction
function-object, so...Because we are at the top of the object graph and want to maintain consistency of expected behavior we configure the
[[Prototype]]
ofFunction
to beFunction.prototype
.Thus ensuring
Function instanceof Function === true
.We can show that
Function.prototype
is a special function-object because:...and every user-defined function (other than fat-arrows) has an object on its prototype property.
Because of all the above:
This may might look odd, but as previously noted, at the top of the object graph we have a limited set of candidate objects to point to.
TC-39 now needed to identify what the
[[Prototype]]
of the[[Prototype]]
ofObject
was. Per the above we know that the[[Prototype]]
ofObject
isFunction.prototype
.In some sense we are now above
Function.prototype
in the object graph, so a specialObject
instance (the "prototype object") was chosen to be this value.This means that the top of every prototype chain can be conveniently tied up with
Object.prototype
.This of course, also meets the desireable requirement that everything "is an object".
At this point we need to complete the object graph, so we set the
[[Prototype]]
ofObject.prototype
to benull
.