函數(shù)是一等公民
函數(shù)式編程的目的
函數(shù)式編程的目的是使用函數(shù)來抽象作用在數(shù)據(jù)之上的控制流和操作迷守,從而在系統(tǒng)中消除副作用并減少對狀態(tài)的改變煞肾。
函數(shù)式編程的概念
- 聲明式編程
- 純函數(shù)
- 引用透明
- 不可變性
聲明式編程
函數(shù)式編程屬于聲明是編程范式:這種范式會描述一系列的操作扫俺,但并不會暴露它們是如何實現(xiàn)的或是數(shù)據(jù)流如何傳過它們画饥。
聲明式是將程序的描述與求值分離開來岭皂。它關(guān)注如何用各種表達式來描述程序邏輯见擦,而不一定要指明其控制流或狀態(tài)關(guān)系的變化摘完。
純函數(shù)
純函數(shù)指沒有副作用的函數(shù)姥饰。相同的輸入有相同的輸出,就跟我們上學(xué)學(xué)的函數(shù)一樣孝治,常常這些情況會產(chǎn)生副作用列粪。
改變一個全局的變量审磁、屬性或數(shù)據(jù)結(jié)構(gòu)
改變一個函數(shù)參數(shù)的原始值
處理用戶輸入
拋出一個異常
屏幕打印或記錄日志
查詢 HTML 文檔,瀏覽器的 Cookie 或訪問數(shù)據(jù)庫
純函數(shù)的性質(zhì)
- 僅取決于提供的輸入岂座,而不依賴于任何在函數(shù)求值或調(diào)用間隔時可能變化的隱藏狀態(tài)和外部狀態(tài)态蒂。
- 不會造成超出作用域的變化,例如修改全局變量或引用傳遞的參數(shù)费什。
引用透明
引用透明是定義一個純函數(shù)較為正確的方法钾恢。純度在這個意義上表面一個函數(shù)的參數(shù)和返回值之間映射的純的關(guān)系。如果一個函數(shù)對于相同的輸入始終產(chǎn)生相同的結(jié)果鸳址,那么我們就說它是引用透明瘩蚪。
使用純函數(shù)的代碼絕不會更改或破壞全局狀態(tài),有助于提高代碼的可測試性和可維護性
函數(shù)式編程采用聲明式的風(fēng)格稿黍,易于推理疹瘦,提高代碼的可讀性。
函數(shù)式編程將函數(shù)視為積木巡球,通過一等高階函數(shù)來提高代碼的模塊化和可重用性言沐。
可以利用響應(yīng)式編程組合各個函數(shù)來降低事件驅(qū)動程序的復(fù)雜性(這點后面可能會單獨拿一篇來進行講解)。
curry(柯里化)
curry 的概念很簡單:只傳遞給函數(shù)一部分參數(shù)來調(diào)用它酣栈,讓它返回一個函數(shù)去處理剩下的參數(shù)险胰。
組合函數(shù)
undercore實現(xiàn)
function aCompose(...args) {
let length = args.length
let count = length - 1
let result
return function f1 (...arg1) {
result = args[count].apply(this, arg1)
if (count <= 0) {
count = length - 1
return result
}
count--
return f1.call(null, result)
}
}
函數(shù)式實現(xiàn)
function compose(...args) {
return (result) => {
return args.reduceRight((result, fn) => {
return fn(result)
}, result)
}
}
注意:要傳給 compose 函數(shù)是有規(guī)范的,首先函數(shù)的執(zhí)行是從最后一個參數(shù)開始執(zhí)行钉嘹,一直執(zhí)行到第一個鸯乃,而且對于傳給 compose 作為參數(shù)的函數(shù)也是有要求的鲸阻,必須只有一個形參跋涣,而且函數(shù)的返回值是下一個函數(shù)的實參。