I\'ve been reading about prototype chain in JavaScript and came to two slightly different definitions. It is said that every object in JavaScript has a prototype and that pr
What is the end of prototype chain in javascript --
null
orObject.prototype
? Or are null and Object.prototype one and the same thing?
null
. Consider this code in a normal JavaScript environment:
var o = {};
console.log(o.i_am_a_property_that_does_not_exist);
That property accessor operation (o.i_am_a_property_that_does_not_exist
) ends up going to the OrdinaryGet abstract operation defined by the specification with O set to the o
object above and P set to "i_am_a_property_that_does_not_exist"
. That operation starts like this:
If desc is undefined, then
a. Let parent be ? O.[GetPrototypeOf].
b. If parent is null, return undefined.
c. Return ? parent.[[Get]](P, Receiver).
...
For my example above, that [[Get]] operation in 3.c. ends up calling OrdinaryGet recursively until we run out of prototypes. As we can see, the chain ends when we reach null
.
Moreover, it's entirely possible to have an object with a prototype chain that doesn't include Object.prototype
at all (we'll see some in a moment). So clearly Object.prototype
can't be the end of the prototype chain.
Are objects, which are not created from object literals, not linked to
Object.prototype
?
The vast majority will be linked to Object.prototype
directly or indirectly. Consider:
function Thing() {
}
var t = new Thing();
t
's prototype is the object referenced by Thing.prototype
. Thing.prototype
's prototype is Object.prototype
. So t
is linked to Object.prototype
(indirectly).
But it's entirely possible for an object not to be linked to Object.prototype
. Here's one way:
var o = Object.create(null);
Object.create
lets us create an object with the prototype we specify in the first argument (null
in the above). So o
above has no prototype, its [[Prototype]] internal slot (where objects remember their prototypes) is null
.
Here's another:
function Thing() {
}
Thing.prototype = Object.create(null);
var t = new Thing();
In that case, although t
has a prototype, its prototype's prototype is null; t
isn't linked to Object.prototype
at all.
Say I have an object
var x = { len: 4, breadth: 5}
. Would JavaScript automatically create it's prototypex.prototype
.
An object's prototype is not a property called prototype
, so no, the JavaScript engine wouldn't create x.prototype
. An object's prototype is linked via its [[Prototype]] internal slot, which is not directly observable but can be retrieved via Object.getPrototypeOf
. (And if the object derives from Object.prototype
, then on browsers only [in theory], you can use the Annex B [browser-only] __proto__ property from Object.prototype
to access it. But not all objects have that property, because...not all objects inherit from Object.prototype
!)
The prototype
property is just used on functions to determine what object to use as the [[Prototype]] of new objects created via new
with that function. Non-function objects don't have it, and if they did, it wouldn't be any more special than a property called foo
or bazinga
.
And how long would the prototype chain be? Would
x.prototype
have only one prototypeObject.prototype
making a 3 point chain?
You're close, but again, the prototype
property is not the prototype of the object, and non-function objects typically won't have a prototype
property. For var x = { len: 4, breadth: 5}
, the inheritance chain would be:
x
x
's [[Prototype]] (which is Object.prototype
)Object.prototype
's [[Prototype]], which is null
So quite short; 1, 2, or 3 depending on whether you want to count x
and whether you want to count null
.
How does JavaScript internally creates automatic prototypes?
It doesn't, other than the ones defined by the spec (e.g., Object.prototype
and such). The closest it comes is that for all function
functions, the JavaScript engine automatically creates an object and assigns that object to the function's prototype
property just in case that function is used as a constructor (via new
). (It doesn't do this with arrow functions or generators.)