Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Function.prototype.call.bind work?

I am having some trouble wrapping my head around this function:

var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]​​​​​​​​​​​​​​​​​​​​​​​​​​​

How does this function accept an argument as seen in line 2?

like image 760
levi Avatar asked Jun 20 '12 14:06

levi


People also ask

What is function prototype bind?

prototype. bind() The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

How does bind function work?

The bind() method creates a new function, when invoked, has the this sets to a provided value. The bind() method allows an object to borrow a method from another object without making a copy of that method. This is known as function borrowing in JavaScript.

What does bind () do in JavaScript?

bind is a method on the prototype of all functions in JavaScript. It allows you to create a new function from an existing function, change the new function's this context, and provide any arguments you want the new function to be called with.

What is use of call () apply () bind () methods?

Call invokes the function and allows you to pass in arguments one by one. Apply invokes the function and allows you to pass in arguments as an array. Bind returns a new function, allowing you to pass in a this array and any number of arguments.


3 Answers

Well,

  • Function.prototype.call references the "call" function, which is used to invoke functions with chosen this values;
  • The subsequent .bind refers to the "bind" function on the Function prototype (remember: "call" is a function too), which returns a new function that will always have this set to the passed-in argument.
  • The argument passed to "bind" is the "toString" function on the Object prototype, so the result of that whole expression is a new function that will run the "call" function with this set to the "toString" function.

The result, therefore, is like this code: Object.prototype.toString.call( param ). Then, the "console.log" call passes that function an array, and there you have it.

edit Note that Object.prototype.toString.call( param ) is like param.toString() really, when "param" is an object. When it's not, then the semantics of the "call" function are to turn it into one in the normal ways JavaScript does that (numbers -> Number, strings -> String, etc).

edit, 24 May2016 — That last sentence above is not accurate with ES2015. New JavaScript runtimes do not "autobox" primitive types when those are involved with a function call as a this value.

like image 109
Pointy Avatar answered Oct 19 '22 02:10

Pointy


I assume you already know what .call and .bind do

toStr is now a function that essentially does:

function toStr( obj ) {
    return Function.prototype.call.call( Object.prototype.toString, obj );
}

I.E it .calls the .call function with context argument set to the .toString function. Normally that part is already taken care of because you normally use .call as a property of some function which sets the function as the context for the .call.

like image 21
Esailija Avatar answered Oct 19 '22 03:10

Esailija


The two lines of code are a function definition and then execution call of that definition with an empty array passed inside. The complexity lies in interpreting what 'this' will point to and why.

To help deduce the value of this I copied content from two links below to MDN's definitions of call and bind.

The bind() function creates a new function (a bound function) with the same function body as the function it is being called on (the bound function's target function) with the this value bound to the first argument of bind(). Your code looks similar to a 'shortcut function' described on the bind page.

var unboundSlice = Array.prototype.slice; // same as "slice" in the previous example
var slice = Function.prototype.call.bind(unboundSlice);

// ...

slice(arguments);

With call, you can assign a different this object when calling an existing function. this refers to the current object, the calling object.With call, you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.

When toStr is called it passes in an array to bind, of which the this pointer is bound. With bind(), this can be simplified.

toStr() is a bound function to the call() function of Function.prototype, with the this value set to the toStr() function of Array.prototype. This means that additional call() calls can be eliminated.

In essence, it looks like a shortcut function override to the toString method.

like image 3
Nash Worth Avatar answered Oct 19 '22 03:10

Nash Worth