Question on the global Function object and the [[Prototype]] chain

Check out this diagram. I’m trying to understand the .__proto__ / [[Prototype]] relationship from the global Function object to functions call(), apply(), bind() that exist on Function.prototype.

From what I understand, the .__proto__ / [[Prototype]] relationship represents that path/direction the [[Prototype]] chain flows. Why does the global Function object have this relationship towards its methods, but other functions like Foo() and Bar() don’t?

The diagram is a mental map of the code below:

function Foo(who) {
    this.me = who;
}
Foo.prototype.identify = function() {
    return "I am " + this.me;
};

function Bar(who) {
    Foo.call( this, who );
}
Bar.prototype = Object.create( Foo.prototype );

Bar.prototype.speak = function() {
    alert( "Hello, " + this.identify() + "." );
};

var b1 = new Bar( "b1" );
var b2 = new Bar( "b2" );

b1.speak();
b2.speak();

If you’d like more context, this is taken from Ch. 6: Behavior Delegation of YDKJS: this and Object prototypes. Thanks for any help!

I understand the code but I don’t really understand what you are trying to ask.

Are you asking about why custom functions don’t have prototype chain?

So at the top left of the diagram there is the global Function object, represented as just Function() inside a circle. It has two black (non-dotted) arrows pointing to call(), apply(), bind() which is in a circle.

If I understand it correctly, call(), apply(), bind() are methods of Function.prototype.

I was asking if anyone could explain the .__proto / [[Prototype]] relationship arrow pointing from Function() to call(), apply(), bind(). Why does the relationship exist on the global function, but for Foo() and Bar() it exists only on their .prototypes?

I think the code is pretty easy to understand, but the author said that it’s important to understand what’s going on in this diagram.

I hope that’s clearer, if not I’ll try to explain it better.

What confuses me with your question is that both Foo() and Bar() have prototype chain to Function.prototype. which is what __proto__ / [[Prototype]] arrow is about. So, trying to ask a question like:

why prototype chain between Function and Function.prototype is not present in Foo and Bar,

doesn’t really make sense to me. But, I’ll try to answer from what I think you are asking.

As for your question,

I was asking if anyone could explain the .__proto / [[Prototype]] relationship arrow pointing from Function() to call(), apply(), bind().

There is a Function object and its prototype object defines call(), apply(), bind(). But I think you’ve already understood it.

Why does the relationship exist on the global function, but for Foo() and Bar() it exists only on their .prototypes?

(The global function? do you mean Function object or the actual global function Foo()?)

  • All objects inherit from Object and Object inherits from Object.prototype.
  • Function object inherits from Function.prototype.
  • Custom functions are instances of Function object; hence they can access methods in Function.prototype.

Therefore, Foo() and Bar() has access to Function.prototype. However, since their prototype does not inherit from Function because they are not a function.

Having an object where it’s prototype and __proto__ properties is impossible when you play by the book (it would mean that the object created itself). It makes some sense, though: Function is a function itself so it should have been created by a function constructor which is Function. It seems that Brendan Eich is a jolly fellow.

1 Like

Thanks! I think I get what’s going on now.

This is how I understand it. All functions can delegate to Function.prototype's methods, like call(), apply(), bind(). Since the global function Function() is also a function, it can delegate to its methods on its own .property object. It’s a little weird but it’s consistent with the JavaScript rules.

Do I understand this correctly?

Hey thanks again for replying, sorry I wasn’t clear.

There is a .__ proto __ / [[Prototype]] relationship between Function() and call(), apply(), bind(). call(), apply, bind() exist on Function.prototype.

Foo() and Bar() also have methods on their prototype. Foo() has identity() and Bar() has speak(). Foo() only has the .prototype relationship to its method identity() and Bar() is the same with speak().

However, Function has two relationships to its methods on Function.prototype. One of these is the one I mentioned earlier, .__ proto __ / [[Prototype]. I understand this relationship to just mean the link/path of the [[Prototype]] chain. Foo() and Bar() have this relationship, but it points to Function(); not to their own prototype methods identity() and speak(). I was wondering why Function() was unique in this regard.

I think I may have found an explanation for this, taking into account @marzelin’s answer.

All functions can delegate to Function.prototype's methods, like call(), apply(), bind(). Since the global function Function() is also a function, it can delegate to its methods on its own .property object. Thus that relationship arrow is there. It’s a little weird but it’s consistent with JavaScript’s rules.

I think the code is pretty easy to understand, but the author said that it’s important to understand what’s going on in this diagram.

I hope that’s clearer, if not I’ll try to explain it better.

Thanks for clarifying and I think you’ve almost got it.
This might help along with what you’ve already understood:

19.2.2 Properties of the Function Constructor#

The Function constructor is itself a built-in function object. The value of the [[Prototype]] internal slot of the Function constructor is the intrinsic object %FunctionPrototype%.

It’s from the latest ECMAScript specification.

1 Like

I think you ‘feel’ the subject but you still need some time to clarify your understanding (.property object??).

Yea that’s a very straightforward answer :slight_smile: , thanks again.

I really wish the author talked more about the Function constructor in the text.

Well to be honest I think I understand the .prototype object and the [[Prototype]] chain well enough, but the Function constructor seems to be unique.

I guess it’s hard for me to know though, since I’m new to all of this.

1 Like