关于Function.prototype.bind()的困惑

时间:2012-08-01 14:11:29

标签: javascript bind ecmascript-5 partial-application

我非常喜欢ES5的Function.prototype.bind和currying参数(基本上为函数创建默认参数)。

我有点傻逼,但我不能为我的生活找出自己的构造了。这是我的游乐场:

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 );

此日志输出如下:

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

但我不明白{what: 'dafuq'}对象如何在this内作为foo的参考。据我了解,我们正在创建一个绑定调用Function.prototype.call。让我们快速检查.bind()的MDN概要:

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

因此,thisArg .callhello函数,后跟参数列表。基本上会发生什么呢

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

...呃现在我的大脑有点疼。我想我现在有了一个想法会发生什么,但请有人找到可靠的单词来详细解释它。

  • {what: 'dafuq'}如何成为this reference

3 个答案:

答案 0 :(得分:8)

你没有打电话给.bind(thisArg, args),而是打电话 Function.prototype.bind.call(thisArgUsedByCall, thisArgUsedByBind, argument)

显示发生情况的另一种方式:

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

答案 1 :(得分:6)

  

但我不明白{what: 'dafuq'}对象是如何在foo中作为参考的?

这是因为foo实际上是call方法,hello函数绑定为调用上下文,并且该对象绑定为第一个参数。 .call 的第一个参数设置其调用上下文的调用上下文。既然你绑定了它,就意味着对象总是调用上下文。


这样说吧......

您已将.call的调用上下文绑定到hello

这与做......实际上是一样的。

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

您还将.call的第一个参数绑定到{what: "dafuq"},因此这实际上与执行... {/ p>相同

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

最后,你将.call的第二个参数限制为2,所以这实际上和做... {/ p>

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

答案 2 :(得分:2)

简短的回答是bind使用第一个参数并将其用作 this ,但是然后调用消耗第一个参数(这是bind的第二个参数)。

Bind的工作原理如下:

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

变为

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

所以

foo( 42 )

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

成为

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

呼叫的工作原理如下:

fun.call(thisArg, argArgs)

变为

fun(argArgs) // this = thisArg

所以

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

变为

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