Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the end of prototype chain in javascript -- null or Object.prototype?

I've been reading about the prototype chain in JavaScript and came to two slightly different definitions. It is said that every object in JavaScript has a prototype and that prototype in turn has another prototype.

The top prototype (Grand) may also have prototype and the chain can continue. Now the chain will stop at one last object. JavaScript: The Good Parts says the chain terminates at Object.prototype and MDN says null is the final link where the chain terminates.

Javascript: The Good Parts

Every object is linked to a prototype object from which it can inherit properties. All objects created from object literals are linked to Object.prototype, an object that comes standard with JavaScript.


MDN

Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. null, by definition, has no prototype, and acts as the final link in this prototype chain.

  • What is the end of prototype chain in JavaScript -- null or Object.prototype? Or are null and Object.prototype one and the same thing?
  • Are objects, which are not created from object literals, not linked to Object.prototype?
  • Say I have an object var x = { len: 4, breadth: 5}. Would JavaScript automatically create its prototype x.prototype? And how long would the prototype chain be? Would x.prototype have only one prototype, Object.prototype, making a 3 point chain?
  • How does JavaScript internally create automatic prototypes?
like image 639
user31782 Avatar asked Apr 18 '16 11:04

user31782


3 Answers

  1. It is like, if New York has an envelope and inside, it says Colorado, and Colorado has an envelope, and inside, it says San Francisco, and San Francisco has an envelope, and inside, it says "none". So is San Francisco end of the chain, or is "none" the end of chain? It may depend on how you look at it. But one thing is for sure: it points up and up the chain, for inheritance purpose (prototypal inheritance), until it reaches null, which means can't go further up. And make sure you know that, to go up and up the chain, it is __proto__. It is not prototype.

  2. Object.prototype, Animal.prototype are different from x.__proto__. The former are function objects (Object, Animal) having a prototype property pointing to a prototype object. And x.__proto__ is how the prototype chain is followed upward. To go up and up, it is x.__proto__.__proto__ and so on. See JavaScript's Pseudo Classical Inheritance diagram to understand it more.

  3. Object.prototype refers to a prototype object. Quoted from MDN, null "represents the intentional absence of any object value. It is one of JavaScript's primitive values." So Object.prototype and null are not the same thing.

  4. All JavaScript objects will have obj.__proto__ referring ultimately to what Object.prototype refers to. If it is not obj.__proto__, then it is obj.__proto__.__proto__. If not, just go up, and up, and it will reach the prototype object which Object.prototype refers to. And at this point, when you go up one level (by adding a .__proto__, then you get null. You can try it in Google Chrome's developer's tool:

    x = { a : 1 }
    > Object {a: 1}
    
    x.__proto__ === Object.prototype
    > true
    
    x.__proto__.__proto__
    > null
    
    Object.prototype.__proto__
    > null
    
like image 105
nonopolarity Avatar answered Oct 31 '22 10:10

nonopolarity


What is the end of prototype chain in JavaScript ...?

Null. The only authority on the language is ECMA-262.

Are objects, which are not created from object literals, not linked to Object.prototype?

They may or many not be, e.g.

var x = Object.create(null)

has a [[Prototype]] of null, whereas:

var y = {};

has a [[Prototype]] of Object.prototype.

Say I have an object var x = { len: 4, breadth: 5}. Would JavaScript automatically create its prototype x.prototype?

No. Function objects have default prototype objects. Plain objects have a default [[Prototype]] (i.e. internal prototype property) that is Object.prototype (unless constructed as above).

And how long would the prototype chain be? Would x.prototype have only one prototype, Object.prototype, making a 3 point chain?

Two values: Object.prototype and null.

How does JavaScript internally create automatic prototypes?

However it likes, the language specification does not define implementation, only behaviour.

like image 25
RobG Avatar answered Oct 31 '22 10:10

RobG


What is the end of prototype chain in javascript -- null or Object.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:

  1. Assert: IsPropertyKey(P) is true.
  2. Let desc be ? O.[GetOwnProperty].
  3. If desc is undefined, then

a. Let parent be ? O.[GetPrototypeOf].

b. If parent is null, return undefined.

c. Return ? parent.[[Get]](P, Receiver).

  1. ...

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 prototype x.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. (There's also the legacy __proto__ property, but it's best not to use it, not least because A) It's an optional part of the specification, and B) Not all objects inherit from Object.prototype, which is where __proto__ is defined.)

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 prototype Object.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.)

like image 45
T.J. Crowder Avatar answered Oct 31 '22 09:10

T.J. Crowder