亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

求解釋,這里的arguments是同一個arguments嗎?

求解釋,這里的arguments是同一個arguments嗎?

SMILET 2022-06-16 17:11:37
if(typeof Function.prototype.bind==="undefined"){Function.prototype.bind=function(thisArg){var fn=this,slice=Array.prototype.slice,args=slice.call(arguments,1);//arguments1return function(){return fn.apply(thisArg,args.concat(slice.call(arguments)));//arguments2}};}
查看完整描述

2 回答

?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

 這里確實是兩個arguments,而且這兩個arguments是不同的。

  首先你要理解prototype里bind()函數的含義,bind()函數和apply()、call()函數一樣,都是用來改變函數的上下文環境(即函數中this所指代的對象),與之不同的是,apply()和call()都是立即執行獲取結果,而bind()可以返回一個已經改變了上下文環境的函數,供日后調用。而這個函數本身是有參數的,這里bind()函數就是可以在函數獲取上下文環境時給其傳參,同時也可以在函數調用時給其傳參,所以這里會有兩個arguments。

  舉個例子吧,比方你有一個可變基數的累加函數:


var add = function() {    var sum = this.base    for (var i = 0, c; c = arguments[i++];)        sum += c    return sum}

  在這個函數中,基數值base是通過上下文環境決定的,如果基數是1,那么add(1)的結果就是2,如果基數是10,那么add(1)的結果就是11。當然本函數的參數是可變的,當基數為10時,你也可以這么寫:add(1,2,3,4),其結果為10+1+2+3+4=20。

  那函數的上下文環境怎么決定呢?就是題主所提到的bind()函數。下面我們規定兩個上下文:


var context1 = {    base: 1} var context2 = {    base: 10}

  這樣當你就可以通過bind創造一個基數為1和基數為10的累加函數:


var addbase1 = add.bind(context1, 9)var addbase10 = add.bind(context2)

  什么?你問我為什么addbase1在bind的時候會有兩個參數(context1、9)?因為這里其實等于我在bind的同時就給addbase1這個函數開始傳參啦,這個就是題主題目中的第一個arguments。還記得那個切片arguments.slice(1)么?就是把提供上下文的參數context1切掉了,保留了傳給addbase1的參數9。

  當然,在定義了函數之后我也可以正常傳參,如:


addbase1(1, 2, 3, 4)  //結果為20addbase10(1, 2, 3, 4) //結果也是20

  這里的1,2,3,4就是題主所謂的第二個arguments,而我們看到函數addbase1的結果和addbase10的結果一樣,就是因為在bind函數里有一行concat,將我們兩次傳入的arguments結合了起來,使得addbase1的過程變成:1(基底)+9(第一次傳參)+1+2+3+4 = 20

  但是要注意的時,第一次傳參的arguments和第二次傳參的arguments是不同的,因為第一次傳入的參數會被保存在函數的閉包中,成為一種currying的屬性,不會隨著以后的傳參而改變(即保存在了代碼第五行的args中)。也就是說,當你再次執行如下代碼時:


addbase1(1, 2, 3, 4)  //結果依然是20,實際上addbase1和addbase10一樣了

  實際上也就是說,在bind時傳入的參數,也就是第一個arguments,會影響函數的屬性;在調用時傳入的參數,也就是第二個arguments,不會影響函數的性質。

  希望能幫到你。


查看完整回答
反對 回復 2022-06-20
?
慕虎7371278

TA貢獻1802條經驗 獲得超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,第二個則是指返回的那個函數的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);



查看完整回答
反對 回復 2022-06-20
  • 2 回答
  • 0 關注
  • 143 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號