2

I would like to understand the relation between Function and function in javascript.

Let me make an example:

Function.prototype.bind // function () { [native code] }

var foo = function () {};
foo.bind; //function () { [native code] }

My question is
Function.prototype.bind and foo.bind refers to the same code?
If yes, can someone explain me the relation?

Lorraine Bernard
  • 13,000
  • 23
  • 82
  • 134
  • I think this is more of a question about inheritance than what this particular situation entails. – David G Sep 18 '12 at 14:45

5 Answers5

3

Yes, the prototype of any function() {} always points to the Function prototype. An easy way to find out is checking with using deep equality:

var foo = function () {};
foo.bind === Function.prototype.bind // -> true

You can actually create a Function instance using the new operator and passing the body and arguments (although this is really not recommended):

var f = new Function("return 'hello world'");
f() // -> hello world
Daff
  • 43,734
  • 9
  • 106
  • 120
1

Maybe you, just like me some weeks ago, are wondering about the difference between adding a function to this (inside the outer function) and adding it via the prototype keyword. The key difference is, that the later is only added once to the prototype object, while the first (where you assign the new function to this and return this) is added every time you make a new instance of your function(object).

I found this post really good: Use of 'prototype' vs. 'this' in JavaScript?

Community
  • 1
  • 1
sra
  • 6,338
  • 3
  • 20
  • 17
  • 1
    actually, the highest-voted answer to that question is entirely wrong or at least very imprecise. You rather should look for a good tutorial like the ones listed at https://developer.mozilla.org/en-US/learn/javascript – Bergi Sep 18 '12 at 18:36
  • Why the highest-voted answer to that question is entirely wrong? Could you explain your opinion in few words? thanks. – Lorraine Bernard Sep 20 '12 at 07:13
0

Yep, check it out:

> (function (){}).bind === Function.prototype.bind
true

And to prove it's not just doing string equality:

> (function(){} === function(){})
false
> ((""+function(){}) === (""+function(){}))
true    

This is because the internal [[Prototype]] field of any function (which can be accessed in Google Chrome with __proto__) will always be Function.prototype:

> Function.prototype
function Empty() {}
> (function (){}).__proto__
function Empty() {}
> Function.prototype === (function (){}).__proto__
true

If a field of a given name is looked up in an object and not found, the prototype inheritance chain is followed until you get to an object that does have that field. In this case, our function doesn't have a bind property, so bind is taken from the prototype:

> (function (){}).__proto__.bind
function bind() { [native code] }
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • Your proof to show that functions are not compared as strings is hard to understand. Also, you should fix some mix-ups in the text after that – Bergi Sep 18 '12 at 15:04
  • my proof was that i had a function create two functions which have the same textual representation, but the functions aren't equal when using `==` or `===`. thanks for hint about text mix-ups; i fixed it up a bit – Claudiu Sep 18 '12 at 15:46
  • I actually catched the internal *property* `[[prototype]]` :) Yes, I understood what you did, however functions are non-primitive values and always compared by reference - but you'd need to know what the equality operators are doing, and if you know that you also knew that functions are objects. Btw: Showing that `(function(){} !== function(){})` would have been much shorter… – Bergi Sep 18 '12 at 15:57
  • @Bergi: ah thanks. yes that check is much shorter, i changed that. i know functions are objects, i just wasn't sure whether `==` did string coercion between two objects, so i checked by doing a test myself instead of looking it up – Claudiu Sep 18 '12 at 17:55
0

All JavaScript function [objects] (like foo) are instances of the Function constructor, and inherit from the Function.prototype. You can easily check it:

> (function foo(){…}) instanceof Function
true
> (function foo(){…}).bind === Function.prototype.bind
true
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Function.prototype.bind and foo.bind refers to the same code?

Absolutely! You might have come across a phrase like JavaScript is a functional language or in JS, functions are first class objects. That means that the logic of properties and methods apply to functions, just as they do for any object (Arrays, Date, Object,...)
The main Function hold the prototype that defines all basic properties and methods that all functions have. Rather than assigning new function objects to each function, it's just far more efficient to assign them to 1 object, to which all function objects points.

This means, like other have pointed out here:

function foo()
{};
foo.bind === Function.prototype.bind;

But this also means that you can augment both the prototype and the individual function objects:

Function.prototype.getName = function()
{
    return this.name;
}
foo.getName();//foo

Again, here foo.getName === Function.prototype.getName, but once we assign directly to a single function object:

foo.getName = function(){ return 'bar';};

It stands to reason that foo.getName !== Function.prototype.getName... just play around with the Function prototype, and how it affects the behaviour of each function individually. It's good fun ;P

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149