函數(shù)式編程是一種編程范式,常見(jiàn)的編程范式有函數(shù)式編程,命令式編程。
命令式編程是面向計(jì)算機(jī)硬件的抽象,有變量,賦值語(yǔ)句,表達(dá)式和控制語(yǔ)句,其實(shí)就是一個(gè)指令序列。
函數(shù)式編程是面向數(shù)學(xué)的抽象,將計(jì)算描述為一種表達(dá)式求值,感覺(jué)就是函數(shù)式程序就是一個(gè)表達(dá)式。
本質(zhì)
函數(shù)式編程中的函數(shù)這個(gè)術(shù)語(yǔ)不是指計(jì)算機(jī)中的函數(shù),而是指數(shù)學(xué)中的函數(shù),即自變量的映射。也就是說(shuō)一個(gè)函數(shù)的值僅決定于函數(shù)參數(shù)的值,不依賴(lài)其他狀態(tài)。比如sqrt(x)函數(shù)計(jì)算x的平方根,只要x不變,不論什么時(shí)候調(diào)用,調(diào)用幾次,值都是不變的。
舉個(gè)例子:
[(5+2)-3]*2
傳統(tǒng)的過(guò)程式變成會(huì)這樣寫(xiě):
const a = 5+2;
const b = a-3;
const c = b*2;
那我們的函數(shù)式編程應(yīng)該怎么寫(xiě)呢:
function add(a,b){
return a+b;
}
function subtract(a,b){
return a-b;
}
function multiply(a,b){
return a*b;
}
let result = multiply(subtract(add(5,2),3),2);
特點(diǎn)
- 函數(shù)是"第一等公民"
指的是函數(shù)可以在任何地方定義,在函數(shù)內(nèi)或函數(shù)外,可以作為函數(shù)的參數(shù)和返回值,可以對(duì)函數(shù)進(jìn)行組合。 - 只用"表達(dá)式",不用"語(yǔ)句"
"表達(dá)式"(expression)是一個(gè)單純的運(yùn)算過(guò)程,總是有返回值;"語(yǔ)句"(statement)是執(zhí)行某種操作,沒(méi)有返回值。函數(shù)式編程要求,只使用表達(dá)式,不使用語(yǔ)句。也就是說(shuō),每一步都是單純的運(yùn)算,而且都有返回值。 - 沒(méi)有"副作用"
所謂"副作用",指的是函數(shù)內(nèi)部與外部互動(dòng)(最典型的情況,就是修改全局變量的值),產(chǎn)生運(yùn)算以外的其他結(jié)果。
函數(shù)式編程強(qiáng)調(diào)沒(méi)有"副作用",意味著函數(shù)要保持獨(dú)立,所有功能就是返回一個(gè)新的值,沒(méi)有其他行為,尤其是不得修改外部變量的值。 - 不修改狀態(tài)
函數(shù)式編程只是返回新的值,不修改系統(tǒng)變量。 - 引用透明
引用透明,指的是函數(shù)的運(yùn)行不依賴(lài)于外部變量或"狀態(tài)",只依賴(lài)于輸入的參數(shù),任何時(shí)候只要參數(shù)相同,引用函數(shù)所得到的返回值總是相同的。
好處
- 方便代碼管理
函數(shù)既不依賴(lài)外部的狀態(tài)也不修改外部的狀態(tài),函數(shù)調(diào)用的結(jié)果不依賴(lài)調(diào)用的時(shí)間和位置,這樣寫(xiě)的代碼容易進(jìn)行推理,不容易出錯(cuò)。這使得單元測(cè)試和調(diào)試都更容易。 - 易于“并發(fā)”
由于(多個(gè)線程之間)不共享狀態(tài),不會(huì)造成資源爭(zhēng)用(Race condition),也就不需要用鎖來(lái)保護(hù)可變狀態(tài),也就不會(huì)出現(xiàn)死鎖,這樣可以更好地并發(fā)起來(lái),尤其是在對(duì)稱(chēng)多處理器(SMP)架構(gòu)下能夠更好地利用多個(gè)處理器(核)提供的并行處理能力。 - 代碼簡(jiǎn)潔易于理解
由于函數(shù)式語(yǔ)言是面向數(shù)學(xué)的抽象,更接近人的語(yǔ)言,而不是機(jī)器語(yǔ)言,代碼會(huì)比較簡(jiǎn)潔,也更容易被理解。