JS 函數(shù)式編程思維簡(jiǎn)述(二):高階函數(shù)

  1. 簡(jiǎn)述
  2. 無(wú)副作用(No Side Effects)
  3. 高階函數(shù)(High-Order Function)
  4. 柯里化(Currying)
  5. 閉包(Closure)
  6. 不可變(Immutable)
  7. 惰性計(jì)算(Lazy Evaluation)
  8. Monad

一等公民

? ? ? ?高階函數(shù)(High-Order Function)是函數(shù)式編程思維中的重要條件脊僚,而滿足該條件的編程語(yǔ)言則需要將函數(shù)作為該語(yǔ)言的一等公民來(lái)看待相叁。符合一等公民的條件是:

  • 函數(shù)可以作為一種數(shù)據(jù)類型的值,賦值于一個(gè)變量;
  • 函數(shù)可以作為參數(shù)增淹,在其他函數(shù)中進(jìn)行傳遞椿访;
  • 函數(shù)可以作為返回值,在其他函數(shù)中返回虑润;
image

? ? ? ?將函數(shù)視作一等公民的語(yǔ)言有:JavaScript成玫、Golang、Python拳喻、Scala哭当、Lua、Lisp舞蔽、Scheme等荣病。同時(shí),有著越來(lái)越多的其他語(yǔ)言看上了函數(shù)式編程的出彩之處渗柿,以其特有的方式實(shí)現(xiàn)著符合自身編程方式的高階函數(shù)个盆。

函數(shù)類型

? ? ? ?在 JavaScript 中,函數(shù)是數(shù)據(jù)類型 object 的子類型——即是指一種對(duì)象類型朵栖。我們可以通過(guò) typeof 操作符檢測(cè)一個(gè)值是否是一個(gè)函數(shù)類型:

// 一個(gè)函數(shù)聲明
function foo(x){
    return x + 10;
}
typeof foo; // 返回值:'function'

然而颊亮,實(shí)際上在 JavaScript 中,函數(shù)并非是基本的數(shù)據(jù)類型陨溅,函數(shù)隸屬于對(duì)象類型终惑。能夠使用 typeof 操作符進(jìn)行檢測(cè)僅僅是語(yǔ)言提供的便利:

// 聲明一個(gè) number 類型的變量
const n = 13;
// 一個(gè)函數(shù)聲明
function foo(x){
    return x + 10;
}
typeof foo; // 結(jié)果:'function'
typeof n; // 結(jié)果:'number'

// 檢測(cè) n 所持有的值是否是對(duì)象
n instanceof Object; // 結(jié)果:false

// 檢測(cè) foo 所持有的值是否是對(duì)象
foo instanceof Function; // 結(jié)果:true
Function instanceof Object; // 結(jié)果:true
foo instanceof Object; // 結(jié)果:true

可見(jiàn),函數(shù)是一個(gè)隸屬于 Function 的對(duì)象门扇,而 Function 本身又隸屬于頂層 Object 雹有,是它的子對(duì)象。因此臼寄,一個(gè)函數(shù)的實(shí)例霸奕,也隸屬于 Object ,他們之間擁有間接的繼承關(guān)系吉拳。
? ? ? ?很多有 面向?qū)ο?/code> 經(jīng)驗(yàn)的同學(xué)可能會(huì)想质帅,實(shí)例化對(duì)象不是通過(guò) new 關(guān)鍵字調(diào)用類的構(gòu)造函數(shù)來(lái)進(jìn)行的嗎?這個(gè)問(wèn)題很簡(jiǎn)單:拿 Java 例舉留攒,Java 中擁有字面量形式的對(duì)象聲明方式 String str = "I like Java!";煤惩,聲明變量 str 的過(guò)程中實(shí)際上也構(gòu)建了一個(gè)字符串對(duì)象,并沒(méi)有顯式的使用關(guān)鍵字 new 炼邀。
? ? ? ?在 JavaScript 中魄揉,以字面量的方式構(gòu)建對(duì)象有很多種,比如:

// 數(shù)組字面量
const arr = [1, 2, 3];
// 對(duì)象字面量
const obj = {id : 'xx001'};
// 函數(shù)字面量
function foo(){}            // 函數(shù)聲明
const bar = function(){}    // 函數(shù)表達(dá)式
const baz = (x) => x + 3;   // ES6提供的lambda表達(dá)式函數(shù)

函數(shù)入?yún)?/h3>

? ? ? ?由于函數(shù)也是一個(gè)對(duì)象拭宁,因此函數(shù)也可以作為其他函數(shù)的參數(shù)洛退,作為入?yún)ⅲ?/p>

// 一個(gè)函數(shù)聲明
const add2 = (x) => x + 2;          // 參數(shù)x基礎(chǔ)上加2的函數(shù)
const sub2 = (x) => x - 2;          // 參數(shù)x基礎(chǔ)上減2的函數(shù)
const result = (y, f) => y * f(y);  // 參數(shù)y基礎(chǔ)上乘以 函數(shù)參數(shù)f 的運(yùn)算結(jié)果

result(4, add2);    // 結(jié)果: 24
result(4, sub2);    // 結(jié)果: 8

? ? ? ?在 JavaScript 內(nèi)置對(duì)象中票彪,也有非常多的函數(shù)入?yún)?shí)例,比如 Array.prototype.map 函數(shù)的簡(jiǎn)單實(shí)現(xiàn):

// 一個(gè)高仿的 Array.prototype.map 函數(shù)
const map = function(arr, f){
    const t = []; 
    for(let i=0;i<arr.length; t.push(f(arr[i],i++,arr)));
    return t;
}
// 聲明一個(gè)數(shù)組
const a1 = [1,2,3,4];
// map函數(shù)調(diào)用:參數(shù) f 所示為每一個(gè)值乘以3不狮,并且返回一個(gè)新數(shù)組
const a2 = map(a1, (e) => e*3); // 結(jié)果:[3, 6, 9, 12]

函數(shù)返回值

? ? ? ?函數(shù)可以作為參數(shù)降铸,當(dāng)然也可以作為返回值。作為返回值的函數(shù)摇零,常用于緩存上一個(gè)函數(shù)的執(zhí)行狀態(tài):

// 一個(gè)函數(shù)聲明
const add2 = (x) => x + 2;          // 參數(shù)x基礎(chǔ)上加 2 的函數(shù)
const mul2 = (x) => x * 2;          // 參數(shù)x基礎(chǔ)上乘以 2 的函數(shù)

// 該函數(shù)用于計(jì)算推掸,計(jì)算結(jié)果不會(huì)直接得出,而是緩存了用于計(jì)算的兩個(gè)函數(shù)
const calc = function(f1, f2){
    return (y) => f1( f2(y) );
}

// 根據(jù)緩存順序不同驻仅,生成的新的函數(shù)執(zhí)行過(guò)程也不同
const c01 = calc(add2, mul2); 
c01(3); // 結(jié)果: 8

const c02 = calc(mul2, add2); 
c02(3); // 結(jié)果:10
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谅畅,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子噪服,更是在濱河造成了極大的恐慌毡泻,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件粘优,死亡現(xiàn)場(chǎng)離奇詭異仇味,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)雹顺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門丹墨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人嬉愧,你說(shuō)我怎么就攤上這事贩挣。” “怎么了没酣?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵杠览,是天一觀的道長(zhǎng)滴劲。 經(jīng)常有香客問(wèn)我济锄,道長(zhǎng)催训,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任闪金,我火速辦了婚禮疯溺,結(jié)果婚禮上论颅,老公的妹妹穿的比我還像新娘哎垦。我一直安慰自己,他們只是感情好恃疯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布漏设。 她就那樣靜靜地躺著,像睡著了一般今妄。 火紅的嫁衣襯著肌膚如雪郑口。 梳的紋絲不亂的頭發(fā)上鸳碧,一...
    開(kāi)封第一講書(shū)人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音犬性,去河邊找鬼瞻离。 笑死,一個(gè)胖子當(dāng)著我的面吹牛乒裆,可吹牛的內(nèi)容都是我干的套利。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鹤耍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼肉迫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起稿黄,我...
    開(kāi)封第一講書(shū)人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤喊衫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后杆怕,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體族购,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年陵珍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了联四。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡撑教,死狀恐怖朝墩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伟姐,我是刑警寧澤收苏,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站愤兵,受9級(jí)特大地震影響鹿霸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秆乳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一懦鼠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧屹堰,春花似錦肛冶、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至荣刑,卻和暖如春馅笙,著一層夾襖步出監(jiān)牢的瞬間伦乔,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工董习, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留烈和,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓皿淋,卻偏偏與公主長(zhǎng)得像斥杜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沥匈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

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