2 回答

TA貢獻2012條經(jīng)驗 獲得超12個贊
這里確實是兩個arguments,而且這兩個arguments是不同的。
首先你要理解prototype里bind()函數(shù)的含義,bind()函數(shù)和apply()、call()函數(shù)一樣,都是用來改變函數(shù)的上下文環(huán)境(即函數(shù)中this所指代的對象),與之不同的是,apply()和call()都是立即執(zhí)行獲取結果,而bind()可以返回一個已經(jīng)改變了上下文環(huán)境的函數(shù),供日后調(diào)用。而這個函數(shù)本身是有參數(shù)的,這里bind()函數(shù)就是可以在函數(shù)獲取上下文環(huán)境時給其傳參,同時也可以在函數(shù)調(diào)用時給其傳參,所以這里會有兩個arguments。
舉個例子吧,比方你有一個可變基數(shù)的累加函數(shù):
var add = function () { var sum = this .base for ( var i = 0, c; c = arguments[i++];) sum += c return sum } |
在這個函數(shù)中,基數(shù)值base是通過上下文環(huán)境決定的,如果基數(shù)是1,那么add(1)的結果就是2,如果基數(shù)是10,那么add(1)的結果就是11。當然本函數(shù)的參數(shù)是可變的,當基數(shù)為10時,你也可以這么寫:add(1,2,3,4),其結果為10+1+2+3+4=20。
那函數(shù)的上下文環(huán)境怎么決定呢?就是題主所提到的bind()函數(shù)。下面我們規(guī)定兩個上下文:
var context1 = { base: 1 } var context2 = { base: 10 } |
這樣當你就可以通過bind創(chuàng)造一個基數(shù)為1和基數(shù)為10的累加函數(shù):
var addbase1 = add.bind(context1, 9) var addbase10 = add.bind(context2) |
什么?你問我為什么addbase1在bind的時候會有兩個參數(shù)(context1、9)?因為這里其實等于我在bind的同時就給addbase1這個函數(shù)開始傳參啦,這個就是題主題目中的第一個arguments。還記得那個切片arguments.slice(1)么?就是把提供上下文的參數(shù)context1切掉了,保留了傳給addbase1的參數(shù)9。
當然,在定義了函數(shù)之后我也可以正常傳參,如:
addbase1(1, 2, 3, 4) //結果為20 addbase10(1, 2, 3, 4) //結果也是20 |
這里的1,2,3,4就是題主所謂的第二個arguments,而我們看到函數(shù)addbase1的結果和addbase10的結果一樣,就是因為在bind函數(shù)里有一行concat,將我們兩次傳入的arguments結合了起來,使得addbase1的過程變成:1(基底)+9(第一次傳參)+1+2+3+4 = 20
但是要注意的時,第一次傳參的arguments和第二次傳參的arguments是不同的,因為第一次傳入的參數(shù)會被保存在函數(shù)的閉包中,成為一種currying的屬性,不會隨著以后的傳參而改變(即保存在了代碼第五行的args中)。也就是說,當你再次執(zhí)行如下代碼時:
addbase1(1, 2, 3, 4) //結果依然是20,實際上addbase1和addbase10一樣了 |
實際上也就是說,在bind時傳入的參數(shù),也就是第一個arguments,會影響函數(shù)的屬性;在調(diào)用時傳入的參數(shù),也就是第二個arguments,不會影響函數(shù)的性質(zhì)。
希望能幫到你。

TA貢獻1802條經(jīng)驗 獲得超4個贊
Function.prototype.bind= function (thisArg){ var fn= this , slice= Array .prototype.slice, args=slice.call(arguments, 1 ); //arguments1 var a1 = arguments; return function (){ alert(a1 == arguments); // 判斷是否為同一個 return fn.apply(thisArg,args.concat(slice.call(arguments))); //arguments2 } }; (( function (){}).bind())( 2 ); // 總是alert出false |
不是。第一個arguments是只thisArg,第二個則是指返回的那個函數(shù)的arguments。
Function.prototype.bind= function (thisArg){ var fn= this , slice= Array .prototype.slice, args=slice.call(arguments, 1 ); //arguments1 alert(arguments[ 0 ]); // alert出1 return function (){ alert(arguments[ 0 ]); // alert出2 return fn.apply(thisArg,args.concat(slice.call(arguments))); //arguments2 } }; (( function (){}).bind( 1 ))( 2 ); |
添加回答
舉報