最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Confusion about Function.prototype.bind() - Stack Overflow

programmeradmin1浏览0评论

I'm a huge fan of ES5's Function.prototype.bind and currying arguments (basically creating default arguments for functions).

I was fooling around with that a bit, but I can't for the life of me figure out my own construct anymore. This is my playground:

function hello( arg1, arg2 ) {
    console.log('hello()');
    console.log('"this" is: ', this);
    console.log('arguments: ', arguments);
}

var foo = Function.prototype.call.bind( hello,{what: 'dafuq'}, 2 );
foo( 42 );

The log output for this is as follows:

hello()
"this" is: Object{ what="dafuq" }
arguments: [2,42]

But I don't understand how on earth the {what: 'dafuq'} object makes its way as a reference for the this within foo. As far as I understand it, we are creating a bound call to Function.prototype.call. Lets check the MDN synopsis for .bind() quickly:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

so, thisArg for .call is the hello function, followed by the arguments list. Basically what happens is this

Function.prototype.call.call( hello, {what: 'dafuq'}, 2);

...uuhhh now my brain hurts a little. I think I have an idea now what happens, but please someone find nice solid words to explain it in detail.

  • how {what: 'dafuq'} bees the this reference

I'm a huge fan of ES5's Function.prototype.bind and currying arguments (basically creating default arguments for functions).

I was fooling around with that a bit, but I can't for the life of me figure out my own construct anymore. This is my playground:

function hello( arg1, arg2 ) {
    console.log('hello()');
    console.log('"this" is: ', this);
    console.log('arguments: ', arguments);
}

var foo = Function.prototype.call.bind( hello,{what: 'dafuq'}, 2 );
foo( 42 );

The log output for this is as follows:

hello()
"this" is: Object{ what="dafuq" }
arguments: [2,42]

But I don't understand how on earth the {what: 'dafuq'} object makes its way as a reference for the this within foo. As far as I understand it, we are creating a bound call to Function.prototype.call. Lets check the MDN synopsis for .bind() quickly:

fun.bind(thisArg[, arg1[, arg2[, ...]]])

so, thisArg for .call is the hello function, followed by the arguments list. Basically what happens is this

Function.prototype.call.call( hello, {what: 'dafuq'}, 2);

...uuhhh now my brain hurts a little. I think I have an idea now what happens, but please someone find nice solid words to explain it in detail.

  • how {what: 'dafuq'} bees the this reference
Share Improve this question edited May 25, 2014 at 17:22 Bergi 665k161 gold badges1k silver badges1.5k bronze badges asked Aug 1, 2012 at 14:11 jAndyjAndy 236k57 gold badges311 silver badges363 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 8

You're not calling .bind(thisArg, args), but
Function.prototype.bind.call(thisArgUsedByCall, thisArgUsedByBind, argument).

A different way to show what happens:

// thisArgUsedByCall is a function
Function.prototype.call(thisArgUsedByCall, ...)   // does the same as:
thisArgUsedByCall.bind(thisArgUsedByBind, argument);

But I don't understand how on earth the {what: 'dafuq'} object makes its way as a reference for the this within foo

It's because foo is effectively the call method with the hello function bound as the calling context, and that object bound as the first argument. The first argument of .call sets the calling context of its calling context. Since you've bound it, it means that object always be the calling context.


Put it this way...

You've bound the calling context of .call to hello.

This is effectively the same as doing...

   hello.call();
// or...
// Function.prototype.call.call(hello);

You've also bound the first argument of .call to {what: "dafuq"}, so this is effectively the same as doing...

hello.call({what: "dafuq"});
// or...
// Function.prototype.call.call(hello, {what: "dafuq"});

And finally, you've bound the second argument of .call to 2, so this is effectively the same as doing...

hello.call({what: "dafuq"}, 2);
// or...
// Function.prototype.call.call(hello, {what: "dafuq"}, 2);

The short answer is that bind consumes the first argument and uses it as this, but then call consumes its first argument (which was bind's second argument).

Bind works like this:

fun.bind(thisArg, argArgs...)(x, y, ...)

bees

fun(argArgs..., x, y, ....) // this = thisArg

So

foo( 42 )

is

Function.prototype.call.bind( hello, { what: 'dafuq' }, 2 ) ( 42 )

which bees

Function.prototype.call({ what: 'dafuq' }, 2, 42) // this = hello

Call works like this:

fun.call(thisArg, argArgs)

Bees

fun(argArgs) // this = thisArg

so

call({ what: 'dafuq' }, 2, 42) // this = hello

bees

hello(2, 42) // this = { what: 'dafuq' }
发布评论

评论列表(0)

  1. 暂无评论