亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

一道JavaScript編程題的拓展

lemanli / 2030人閱讀

摘要:背景在下前端小白,近日在刷各種算法編程題,今天碰到一編程題,考點是,雖說簡單,但在解題時發(fā)現(xiàn)了一個挺有意思的東東,特來分享一下。分析及結(jié)論如下原理其實很簡單,其實就是一個函數(shù),將視為一個整體,記作。

背景

在下前端小白,近日在刷各種算法/編程題,今天碰到一編程題,考點是apply,雖說簡單,但在解題時發(fā)現(xiàn)了一個挺有意思的東東,特來分享一下。歡迎各位大佬指點~

正文

話不多說,直接上題目:二次封裝函數(shù)。

已知函數(shù) fn 執(zhí)行需要 3 個參數(shù)。請實現(xiàn)函數(shù) partial,調(diào)用之后滿足如下條件:
1、返回一個函數(shù) result,該函數(shù)接受一個參數(shù)
2、執(zhí)行 result(str3) ,返回的結(jié)果與 fn(str1, str2, str3) 一致

哈哈,這題簡單!稍微學(xué)過js的朋友就能寫出來:

function partial(fn,str1,str2) {
    var result = function(str3) {
        return fn(str1,str2,str3);
    }
    return result;
}

這里用個call可能會顯得有點逼格(笑),當(dāng)然apply,bind也能達到一樣的效果。

function partial(fn,str1,str2) {
    var result = function(str3) {
        return fn.call(null,str1,str2,str3);
    }
    return result;
}

不多停留,我們來看下一題,同樣是二次封裝函數(shù):

實現(xiàn)函數(shù) partialUsingArguments,調(diào)用之后滿足如下條件:
1、返回一個函數(shù) result
2、調(diào)用 result 之后,返回的結(jié)果與調(diào)用函數(shù) fn 的結(jié)果一致
3、fn 的調(diào)用參數(shù)為 partialUsingArguments 的第一個參數(shù)之后的全部參數(shù)以及 result 的調(diào)用參數(shù)

emmmmm,傳入的參數(shù)不固定? 有了! 用arguments~

function partialUsingArguments(fn) {
  var _arguments = Array.prototype.slice.call(arguments,1)
  var result = function() {
    var newArguments = _arguments.concat(Array.prototype.slice.call(arguments,0));
    return fn.apply(null,newArguments)
  }
  return result;
}

唔,好像也沒什么難的,_arguments就是partialUsingArguments第一個參數(shù)后的所有參數(shù)組成的數(shù)組,將它和result的所有參數(shù)合并起來,利用apply傳入fn,ok~解決了!

誒誒?有意思的東西呢?這特么一點意思都沒啊。
說出來你們可能不信,其實我看到這題的時候,雖然我想到了用apply,但我并沒有想到fn.apply(null,newArguments)。那我想到的是什么呢?

Function.prototype.call.apply

什么鬼?我也不知道是在哪看過這東西(也許沒看過),又好像是

Function.prototype.call.call?

還是

Function.prototype.apply.apply

還是

Function.prototype.apply.call?

好像都差不多,媽個雞,試試就知道了!

return Function.prototype.call.apply(fn,newArguments)
瀏覽器一跑,好像對了?不對!我傳入的第一個參數(shù)怎么不見了?
Google之~ 噢~ 原來第一個參數(shù)被吃了。
原來Function.prototype.call.apply(fn,newArguments)同等于fn.call(a,b,c,...z) // newArguments = [a,b,c,...z],這里的...z不是ES6中的...rest哦,只是表示省略了中間的參數(shù)。

知道了原理(并不知道),那就好辦了,我給newArguments數(shù)組的頭部補一個元素上去不就好了~

newArguments.unshift(0);
Function.prototype.call.apply(fn,newArguments)

瀏覽器一跑——沒毛病老鐵!

完了嗎?

并沒有!

既然.call.apply可以用,那其他3個按理來說也能用,況且這里多了一步對數(shù)組的操作,能不能更優(yōu)雅一點呢?(另外3個怎么用,觀眾老爺們心里有答案嗎?)
本著 求知 以及 code less,do more 的精神,我對剩下的3種組合進行了深♂入的研究。

分析及結(jié)論如下

原理其實很簡單,Function.prototype.apply(call)其實就是一個函數(shù),將視為一個整體,記作A。原式就可以轉(zhuǎn)換成:A.apply(參數(shù))A.call(參數(shù)),然后進一步轉(zhuǎn)換,參數(shù)1.A(參數(shù)2),什么參數(shù)、參數(shù)1、參數(shù)2的?
相信大家也看出來了,這里唯一的難點(?)就是參數(shù)。參數(shù)怎么寫呢?

其實很簡單,apply就傳數(shù)組,call就傳一個序列。

applycall的區(qū)別大家肯定知道,我就不多說了。第一個參數(shù)肯定是fn,這個沒跑了。關(guān)鍵就在第二個參數(shù)上。

第二個參數(shù),首先它形式上要看后一個apply/call,如果是apply,我們就傳數(shù)組進去,如果是call,就傳一個序列。然后它的內(nèi)容就要看A了,也就是前一個apply/call,同理,如果是apply,就傳數(shù)組參數(shù),如果是call,就傳序列參數(shù)

所以我們可以得出以下結(jié)果:

Function.prototype.apply.apply(fn,[null,newArguments])
Function.prototype.call.call(fn,null,...newArguments])
Function.prototype.apply.call(fn,null,newArguments])
//上面3式可以實際上等于
fn.apply(null,newArguments)
fn.call(null,...newArguments) //...為擴展運算符,...[arr] = arr[0],arr[1],...arr[n]
fn.apply(null,newArguments)

繞了一大圈,又回來了~ :)
而上面的Function.prototype.call.apply也可以改寫成:

    Function.prototype.call.apply(fn,[null,...newArguments])

從而減少了對數(shù)組newArguments的操作。

寫在最后

第一次寫文章(水貼),十分緊張,刪了改,改完了刪,總覺得寫的不好、十分啰嗦。
可能會有人覺得毫無意義,但我覺得這個倒是可以作為一道面試題。

請在填寫空白內(nèi)容使等式成立:
fn.apply(null,args) = Function.prototype.apply.apply(_____)

如果真的有人遇到,請回來點贊^ ^
也希望此文能多少幫助到前端新人,大家一起學(xué)習(xí),進步!
哪里要是寫不好可以直說!幫助我進步。謝謝!
不廢話了,
完。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/84119.html

Failed to recv the data from server completely (SIZE:0/8, REASON:closed)