2012-08-01 55 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