2012-08-01 35 views
11

的困惑我是ES5的Function.prototype.bind和currying参数(基本上为函数创建默认参数)的狂热粉丝。关于Function.prototype.bind()

我在那儿玩弄了一下,但是我不能在我的生活中找出自己的构造。这是我的游乐场:

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。让我们检查MDN大纲为.bind()迅速:

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

因此,对于thisArg.callhello功能,其次是参数列表。基本上会发生什么事情是这样的

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

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

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

回答

6

但我不知道如何在地球上{what: 'dafuq'}对象使得其方式foo中的这一个参考

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


这样说吧...

你已经绑定的.call呼叫上下文hello

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

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

你也必然的.call的第一个参数{what: "dafuq"},所以这实际上是一样的做...

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

最后,你必然的.call2第二个参数,所以这是有效的一样做......

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

是'foo'是调用方法,但我们永远不会调用'foo.call(thisArg)'对吗?我们直接用'()'调用它。我不明白:p – jAndy 2012-08-01 14:16:03

+0

@jAndy:你使用'.bind'将'.call'的第一个参数绑定到你的对象。因此,“.call”的这个“版本”有一个绑定的第一个参数,它总是将它用作调用上下文。 – 2012-08-01 14:16:39

+0

'.call()'的绑定“版本”应该有'hello'作为thisArg,否?之后,我们执行那个绑定的'.call()',只是传递正式参数。呃,好吧,可能我只是在这里精神上受阻,还在计算它。 – jAndy 2012-08-01 14:21:45

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

好的,这使得它更加明显。好答案。 – jAndy 2012-08-01 14:22:53

2

简短的回答是,绑定消耗的第一个参数并使用它作为这个,但然后调用它的第一个参数(这是绑定的第二个参数)。

绑定的工作原理是这样的:

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' } 
+0

*“(我不知道5从哪里来)”* - 哪五个? – 2012-08-01 15:54:37

+0

看起来它已经修复 - 这是主帖中的一个错字。作为回报编辑我的回复。 – royh 2012-08-01 15:58:16