13

Function.prototype.bind我是 ES5和柯里化参数(基本上是为函数创建默认参数)的忠实粉丝。

我只是在胡闹,但我终其一生都无法弄清楚我自己的构造。这是我的游乐场:

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]

但我不明白这个对象究竟是如何成为 inside的{what: 'dafuq'}参考。据我了解,我们正在创建对. 让我们快速检查 MDN 概要:thisfooFunction.prototype.call.bind()

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

所以,thisArgfor.callhello函数,后面是参数列表。基本上发生的事情是这样的

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

...uuhhh 现在我的大脑有点疼。我想我现在知道会发生什么,但请有人找到很好的可靠词来详细解释它。

  • 怎么{what: 'dafuq'}变成this reference
4

3 回答 3

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);
于 2012-08-01T14:14:20.430 回答
6

但我不明白这个{what: 'dafuq'}对象到底是如何成为 foo 中 this 的参考的

这是因为foo实际上是callhello函数绑定为调用上下文的方法,并将该对象绑定为第一个参数。的第一个参数.call 设置其调用上下文的调用上下文。由于您已绑定它,这意味着该对象始终是调用上下文。


把它这样...

你已经绑定了.callto的调用上下文hello

这实际上与做...

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

您还绑定了.callto的第一个参数{what: "dafuq"},因此这实际上与执行...

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

最后,您已经绑定了.callto的第二个参数2,因此这实际上与执行...

hello.call({what: "dafuq"}, 2);
// or...
// Function.prototype.call.call(hello, {what: "dafuq"}, 2);
于 2012-08-01T14:14:54.217 回答
2

简短的回答是 bind 使用第一个参数并将其用作this,然后 call使用它的第一个参数(这是 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' }
于 2012-08-01T14:43:51.067 回答