前言
函數式程式設計近幾年炒的火熱,其實函數式程式設計其實很早就有了,支援該範式的語言有大名鼎鼎的C、JavaScript、PHP等,那為什麼又進行了一波高潮呢,我們來探究一下。
一、什麼是函數式程式設計
首先了解一下什麼是函數式程式設計:
函數式程式設計(英語:functional programming)或稱函數程式設計、泛函程式設計,是一種程式設計範式,它将電腦運算視為函數運算,并且避免使用程式狀态以及易變對象。其中,λ演算為該語言最重要的基礎。而且,λ演算的函數可以接受函數作為輸入參數和輸出傳回值。
——維基百科
函數式是一種程式設計範式,同時函數式也是一種以函數為核心的程式設計思維方式。
函數是一等公民
函數指派給變量,可以作為參數傳遞,可以作為傳回值。
// 函數可以指派給變量
const foo = function() { return "foo" }
// 函數可以作為參數傳遞,可以作為傳回值
function bar(foo,callback){
const result = foo()
return callback(result)
}
bar(result=>{
console.log(result)
})
二、純函數 & 高階函數
1. 純函數
純函數是函數式程式設計中非常重要的一個概念,簡單來說,就是一個函數的傳回結果隻依賴于它的參數,并且在執行過程中沒有副作用,我們就把這個函數叫做純函數。
- 避免副作用
- 可重複利用
2. 高階函數
以函數輸入或以函數輸出的函數叫做高階函數。
函數輸入參數是函數
函數輸出值為函數
閉包
function foo(name){
return function(){
return "hello," + name
}
}
三、函數式的正确姿勢
1. 避免做疊代
能用函數解決的,避免用for、while、do…while來做,上圖展示的就是以函數式的思維來做一個三明治,第一道工序是把原材料切片剁碎,第二步是累加組合,這樣一個三明治就做出來了。那麼轉換成指令式的做法就是在一個疊代中做所有工序。
2. 避免資料變異
四、優缺點 & 使用場景
1. 優缺點
- 優點
- 簡單易寫易讀
- 可靠性(純函數)
- 惰性求值(高階函數)
- 易于測試
- 組合開發
- 易于” 并發程式設計” ?
- 缺點
- 部分适合犧牲性能
- 消耗記憶體?
2. 使用場景
-
日常代碼中的實踐:處理對資料進行複雜、多次的鍊式操作。
-
Mocha:單元測試庫
- Redux:基于React的工具庫
- Lodash
- Mirror
五、Q & A
1. FP vs OOP
- 核心
- FP:以函數為核心解決問題
- OOP: 以類和對象解決問題,特性:抽象、封裝、繼承、多态
- 動态、擴充機制
- FP:組合+高階函數
- OOP:繼承+多态
2. FP vs IP
比起指令式程式設計(Imperative programming),函數式程式設計更加強調程式執行的結果而非執行的過程,倡導利用若幹簡單的執行單元讓計算結果不斷漸進,逐層推導複雜的運算,而不是設計一個複雜的執行過程。
——維基百科
指令式
const arr = ["zhangsan","lisi","wangwu"]
for(let i = 0; i < arr.length; i++){
if(arr[i]==="lisi"){
arr.splice(i,1)
}
}
console.log(arr)
函數式
const arr = ["zhangsan","lisi","wangwu"]
const result = arr.filter(x=>x!=="lisi")
console.log(result)
參考 & 推薦
- 函數式入門視訊:https://www.youtube.com/watch?v=e-5obm1G_FY
- 函數式優缺點:https://blog.csdn.net/HXCURTAIN/article/details/77619252
- 函數式程式設計:https://www.cnblogs.com/fs0196/p/12686107.html
- 高階函數:https://zhuanlan.zhihu.com/p/49579052
- JavaScript 以函數式為主導的工具庫
- lodash
- ramda
- mirror