user6575289
user6575289

Reputation:

apply() function invoked on Function.prototype.bind in javascript?

I am reading Javascript book 'Speaking Javascript'. In an example the author is simulating the apply function for the Date constructor.

new (Function.prototype.bind.apply(Date, [null,2011,11,24]))

The statement is very confusing and when i try figure out i get confused by the presence of null and that too inside the array. Can anyone help me by explaining the internals of this statement.

Upvotes: 1

Views: 68

Answers (2)

Yury Tarabanko
Yury Tarabanko

Reputation: 45121

Unroll expression step by step

Function.prototype.bind.apply(Date, [null,2011,11,24])

This expression apply's bind function using Date as context (this) with arguments list [null,2011,11,24]

First Function.prototype.bind is just a way to access bind method every function inherits from its prototype. One could use any other function to get it. For example var bind = (function(){}).bind or even var bind = Date.bind

Then fn.apply(ctx, [arg1, ..., argN]) calls fn in context of ctx with given arguments is ctx::fn(arg1, ..., argN) (where :: is bind operator)

Then fn.bind(ctx, arg1, ..., argN) is roughly equivalent to creating a new function with bounded context and partially applied arguments

function(moreArg1, ..., moreArgN) {
   return fn.apply(ctx, [arg1, ..., argN, moreArg1, ..., moreArgN])
}

So bind.apply(fn, [ctx, arg1, ..., argN]) is "same" as fn.bind(ctx, arg1, ..., argN)

Combining both gives

Date.bind(null,2011,11,24)

Upvotes: 2

Poul Kruijt
Poul Kruijt

Reputation: 71901

Soooo, I am in no means an expert, but let me take a crack at it, but let's begin at the end:

The array are arguments which are passed to the Date constructor. You can also use the call method, in this case, you don't use an array, but just put the arguments:

new (Function.prototype.bind.call(Date, null, 2011, 11, 24));

Now it gets more confusing, we got apply on a bind.

apply as we know, calls the function it's applied to. In this case bind. The first argument is the this property and sets the context for the call. In this case Date. The rest of the arguments gets passed to the bind method. The bind method gets called like this:

.bind(null, 2011, 11, 24);

The this arguments is null, and is ignored. bind as you know, returns a callable function. This callable function is the function on which bind is called on. In this case Function.prototype. Which is the prototype of the constructor of Function....

Ahhh, so now we have a constructor, with the this context set to Date, and where the parameters for the constructor are always: 2011, 11, 24.

new (Date.bind(null,2011,11,24));

You can call the constructor using the new keyword, which creates an instance of Date where the year is 2011, the month is December (because January is 0), and the day is the 24th..

Upvotes: 1

Related Questions