1

enter image description here

There's this Object Layout diagram nicely explains the prototype chain in javascript. But it's a bit confusing to me when it comes to the relationships between the followings:

  1. function Object(){}
  2. Object.prototype
  3. function Function(){}
  4. Function.prototype

My question is: Among the above four elements, which comes first? Because I see a cycle among them.

  1. function Object.____proto____ -> Function.prototype
  2. Function.prototype.____proto____ -> Object.prototype
  3. Object.prototype.constructor -> function Object

And also another cycle is:

  1. Function.prototype.constructor -> function Function
  2. function Function.____proto____ -> Function.prototype

How is that possible?

Aaron Shen
  • 8,124
  • 10
  • 44
  • 86

1 Answers1

1

You're mixing up two concepts here, one about the prototype property of of the native constructors and the actual prototype of instances of these native constructs (represented using __proto__). In your first example:

  1. function Object.__proto__ -> Function.prototype
  2. Function.prototype.__proto__ -> Object.prototype
  3. Object.prototype.constructor -> function Object

You have to understand here that Object and Function are themselves functions, as constructors are a form of a function.

In #1, Object is a function, and the actual prototype of all functions is Function.prototype.

In #2, the prototype that function instances inherit itself inherits from Object.prototype. That means that when you look up the prototype chain from a function instance, it will first look at Function.prototype, then Object.prototype.

In #3, the constructor property is meant for object instances, though Object.prototype is an object itself. It does not have a prototype.

For your second example:

  1. Function.prototype.constructor -> function Function
  2. function Function.__proto__ -> Function.prototype

What's in the prototype is meant for instances, not the actual function constructor itself. Because the constructor of any function is Function, that makes sense.

Remember that constructors are still functions? Therefore the prototype of the Function constructor will be Function.prototype. Function.prototype itself is an object, so it will have a __proto__ of Object.prototype.


When you're looking at actual function instances, here's how properties are looked up through the prototype chain:

own properties (on the function itself, functions are special objects)
      |
      |
      ↓
Function.prototype (the __proto__ of the function itself)
      |
      |
      ↓
Object.prototype (the __proto__ of Function.prototype)
      |
      |
      ↓
END (Object.prototype's __proto__ is null)     
Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83