如何讀懂并寫(xiě)出裝逼的函數(shù)式代碼闹蒜?

對(duì)于函數(shù)式的版本,乍一看抑淫,的確令人非常費(fèi)解,仔細(xì)看一下姥闪,你可能就暈掉了始苇,似乎完全就是天書(shū),看上去非常裝逼筐喳,哈哈催式。不過(guò),我感覺(jué)解析那段函數(shù)式的代碼可能會(huì)一個(gè)比較有趣過(guò)程避归。

先看代碼

這個(gè)代碼平淡無(wú)奇荣月,就是從一個(gè)數(shù)組中找到一個(gè)數(shù),O(n)的算法梳毙,找不到就返回 null哺窄。

下面是正常的 old-school 的方式。不用多說(shuō)账锹。

結(jié)果到了函數(shù)式成了下面這個(gè)樣子(好像上面的那些代碼在下面若影若現(xiàn)萌业,不過(guò)又有點(diǎn)不太一樣,為了消掉if語(yǔ)言奸柬,讓其看上去更像一個(gè)表達(dá)式生年,動(dòng)用了 ? 號(hào)表達(dá)式):


為了講清這個(gè)代碼,需要先補(bǔ)充一些知識(shí)廓奕。

Javascript的箭頭函數(shù)

首先先簡(jiǎn)單說(shuō)明一下抱婉,ECMAScript2015 引入的箭頭表達(dá)式档叔。箭頭函數(shù)其實(shí)都是匿名函數(shù),其基本語(yǔ)法如下:

下面是一些示例:

看上去不復(fù)雜吧蒸绩。不過(guò)衙四,上面前兩個(gè) simple 和 max 的例子都把這箭頭函數(shù)賦值給了一個(gè)變量,于是它就有了一個(gè)名字侵贵。有時(shí)候届搁,某些函數(shù)在聲明的時(shí)候就是調(diào)用的時(shí)候,尤其是函數(shù)式編程中窍育,一個(gè)函數(shù)還對(duì)外返回函數(shù)的時(shí)候卡睦。比如下在這個(gè)例子:

其實(shí),在 MakePowerFn 函數(shù)里的那個(gè) PowerFn 根本不需要命名漱抓,完全可以寫(xiě)成:

如果用箭頭函數(shù)表锻,可以寫(xiě)成:

我們還可以寫(xiě)得更簡(jiǎn)潔(如果用表達(dá)式的話,就不需要 { 和 }乞娄, 以及 return 語(yǔ)句 ):

我還是加上括號(hào)瞬逊,和換行可能會(huì)更清楚一些:

好了,有了上面的知識(shí)仪或,我們就可以進(jìn)入一個(gè)更高級(jí)的話題——匿名函數(shù)的遞歸确镊。

匿名函數(shù)的遞歸

函數(shù)式編程立志于用函數(shù)表達(dá)式消除有狀態(tài)的函數(shù),以及for/while循環(huán)范删,所以蕾域,在函數(shù)式編程的世界里是不應(yīng)該用for/while循環(huán)的,而要改用遞歸(遞歸的性能很差到旦,所以旨巷,一般是用尾遞歸來(lái)做優(yōu)化,也就是把函數(shù)的計(jì)算的狀態(tài)當(dāng)成參數(shù)一層一層的往下傳遞添忘,這樣語(yǔ)言的編譯器或解釋器就不需要用函數(shù)棧來(lái)幫你保存函數(shù)的內(nèi)部變量的狀態(tài)了)采呐。

好了,那么搁骑,匿名函數(shù)的遞歸該怎么做斧吐?

一般來(lái)說(shuō),遞歸的代碼就是函數(shù)自己調(diào)用自己靶病,比如我們求階乘的代碼:

在匿名函數(shù)下会通,這個(gè)遞歸該怎么寫(xiě)呢?對(duì)于匿名函數(shù)來(lái)說(shuō)娄周,我們可以把匿名函數(shù)當(dāng)成一個(gè)參數(shù)傳給另外一個(gè)函數(shù)涕侈,因?yàn)楹瘮?shù)的參數(shù)有名字,所以就可以調(diào)用自己了煤辨。?如下所示:

這個(gè)是不是有點(diǎn)作弊的嫌疑裳涛?Anyway木张,我們?cè)偻拢焉厦孢@個(gè)函數(shù)整成箭頭函數(shù)式的匿名函數(shù)的樣子端三。


現(xiàn)在你似乎就不像作弊了吧舷礼。把上面那個(gè)求階乘的函數(shù)套進(jìn)來(lái)是這個(gè)樣子:

首先,先重構(gòu)一下fact郊闯,把fact中自己調(diào)用自己的名字去掉:

然后妻献,我們?cè)侔焉厦孢@個(gè)版本變成箭頭函數(shù)的匿名函數(shù)版:

這里,我們依然還要用一個(gè)fact來(lái)保存這個(gè)匿名函數(shù)团赁,我們繼續(xù)育拨,我們要讓匿名函數(shù)聲明的時(shí)候,就自己調(diào)用自己欢摄。

也就是說(shuō)熬丧,我們要把?

這個(gè)函數(shù)當(dāng)成調(diào)用參數(shù),傳給下面這個(gè)函數(shù):

最終我們得到下面的代碼:

好像有點(diǎn)繞怀挠,anyway, 你看懂了嗎析蝴?沒(méi)事,我們繼續(xù)绿淋。

動(dòng)用高階函數(shù)的遞歸

但是上面這個(gè)遞歸的匿名函數(shù)在自己調(diào)用自己闷畸,所以,代碼中有hard code的實(shí)參吞滞。我們想實(shí)參去掉腾啥,如何去掉呢?我們可以參考前面說(shuō)過(guò)的那個(gè)

我們可以看冯吓,上面的代碼簡(jiǎn)單說(shuō)來(lái)就是,需要一個(gè)函數(shù)做參數(shù)疮跑,然后返回這個(gè)函數(shù)的遞歸版本组贺。那么,我們?cè)趺凑{(diào)用呢祖娘?

連起來(lái)寫(xiě)就是:

但是失尖,這樣讓用戶來(lái)調(diào)用很不爽,所以渐苏,以我們一個(gè)函數(shù)把?HighOrderFact ( HighOrderFact )?給代理一下:

用箭頭函數(shù)重構(gòu)一下掀潮,是不是簡(jiǎn)潔了一些?

上面就是我們最終版的階乘的函數(shù)式代碼琼富。

回顧之前的程序

我們?cè)賮?lái)看那個(gè)查找數(shù)組的正常程序:

先把for干掉仪吧,搞成遞歸版本:

然后,寫(xiě)出帶實(shí)參的匿名函數(shù)的版本(注:其中的if代碼被重構(gòu)成了 鞠眉?號(hào)表達(dá)式):

最后薯鼠,引入高階函數(shù)择诈,去除實(shí)參:

注:函數(shù)式編程裝逼時(shí)一定要用const字符,這表示我寫(xiě)的函數(shù)里的狀態(tài)是 immutable 的出皇,天生驕傲羞芍!

再注:我寫(xiě)的這個(gè)比原來(lái)版的那個(gè)簡(jiǎn)單了很多,原來(lái)版本的那個(gè)又在函數(shù)中套了一套 next郊艘, 而且還動(dòng)用了不定參數(shù)荷科,當(dāng)然,如果你想裝逼裝到天上的纱注,理論上來(lái)說(shuō)畏浆,你可以套N層,呵呵奈附。

現(xiàn)在全度,你可以體會(huì)到,如此逼裝的是怎么來(lái)的了吧斥滤?




轉(zhuǎn)自:https://mp.weixin.qq.com/s/DYTAS5r5tFZyT-JotC4Pkg

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末将鸵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子佑颇,更是在濱河造成了極大的恐慌顶掉,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挑胸,死亡現(xiàn)場(chǎng)離奇詭異痒筒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)茬贵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門簿透,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人解藻,你說(shuō)我怎么就攤上這事老充。” “怎么了螟左?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵啡浊,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我胶背,道長(zhǎng)巷嚣,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任钳吟,我火速辦了婚禮廷粒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘砸抛。我一直安慰自己评雌,他們只是感情好树枫,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著景东,像睡著了一般砂轻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上斤吐,一...
    開(kāi)封第一講書(shū)人閱讀 52,196評(píng)論 1 308
  • 那天搔涝,我揣著相機(jī)與錄音,去河邊找鬼和措。 笑死庄呈,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的派阱。 我是一名探鬼主播诬留,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼菱阵,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼先较!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起顾犹,我...
    開(kāi)封第一講書(shū)人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤腺劣,失蹤者是張志新(化名)和其女友劉穎绿贞,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體橘原,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡籍铁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了趾断。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拒名。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖芋酌,靈堂內(nèi)的尸體忽然破棺而出靡狞,到底是詐尸還是另有隱情,我是刑警寧澤隔嫡,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站甘穿,受9級(jí)特大地震影響腮恩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜温兼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一秸滴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧募判,春花似錦荡含、人聲如沸咒唆。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)全释。三九已至,卻和暖如春误债,著一層夾襖步出監(jiān)牢的瞬間浸船,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工寝蹈, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留李命,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓箫老,卻偏偏與公主長(zhǎng)得像封字,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子耍鬓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 函數(shù)參數(shù)的默認(rèn)值 基本用法 在ES6之前阔籽,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法界斜。 上面代碼檢查函數(shù)l...
    呼呼哥閱讀 3,400評(píng)論 0 1
  • 原文鏈接:https://github.com/EasyKotlin 值就是函數(shù)仿耽,函數(shù)就是值。所有函數(shù)都消費(fèi)函數(shù)各薇,...
    JackChen1024閱讀 5,988評(píng)論 1 17
  • 函數(shù)和對(duì)象 1项贺、函數(shù) 1.1 函數(shù)概述 函數(shù)對(duì)于任何一門語(yǔ)言來(lái)說(shuō)都是核心的概念。通過(guò)函數(shù)可以封裝任意多條語(yǔ)句峭判,而且...
    道無(wú)虛閱讀 4,578評(píng)論 0 5
  • 1.函數(shù)參數(shù)的默認(rèn)值 (1).基本用法 在ES6之前开缎,不能直接為函數(shù)的參數(shù)指定默認(rèn)值,只能采用變通的方法林螃。
    趙然228閱讀 693評(píng)論 0 0
  • 從未停止疏理自我 夢(mèng)疗认,期待完残,掙扎 ...... 時(shí)光不停地雕刻那一顆 混亂的心 終于 在暗灰的色彩里 青春向衰老臣...
    僞禰邇變閱讀 201評(píng)論 0 1