函數(shù)式編程(高階函數(shù))一般是用于寫幫助庫;插件直接面向對象
1.point free 概念:無值操作
2.應用:取得系統(tǒng)api轉純,也就是無值操作,方便組合
Io是處理不純
Monad是處理不存
范疇論函數(shù)式編程和是范疇論的數(shù)學分支,所有概念體系都可以抽象出一個個范疇;彼此之間存在某種關系概念、事物、對象等,都構成范疇。箭頭表示范疇成員之間的關系,正式名稱“態(tài)射”。同一個范疇的所有成員就是不同狀態(tài)的“變形”。通過“態(tài)射”,一個成員可以變形到另一個成員。
所有成員是一個集合;變形關系是函數(shù)
將復雜的函數(shù)符 合成簡單函數(shù)(計算理論、遞歸論或者拉姆達驗算)。運算過程盡量寫成一系列嵌套的函數(shù)調用(抽象)
1)函數(shù)可以賦值給其它變量、也可以作為參數(shù),傳入另一個函數(shù),或者作為別的函數(shù)返回值;
2)不可改變量;在函數(shù)式編程中僅僅代表某個表達式。這里所說的“變量”是不能被修改的。所有的變量只能被賦初始值;
3)map&reduce 是常用的函數(shù)式編程的方法;
map
var?numbers = [4,?9,?16,?25];
function?myFunction() {
??? x = document.getElementById("demo")
??? x.innerHTML = numbers.map(Math.sqrt);
}
輸出結果:2,3,4,5
map() 方法返回一個新數(shù)組,數(shù)組中的元素為原始數(shù)組元素調用函數(shù)處理后的值。
map() 方法按照原始數(shù)組元素順序依次處理元素。
注意:?map() 不會對空數(shù)組進行檢測。
注意:?map() 不會改變原始數(shù)組。
reduce
var numbers = [65, 44, 12, 4];
function getSum(total, num) {
? ? return total + num;
}
function myFunction(item) {
? ? document.getElementById("demo").innerHTML = numbers.reduce(getSum);
}
輸出結果:125
reduce() 方法接收一個函數(shù)作為累加器,數(shù)組中的每個值(從左到右)開始縮減,最終計算為一個值。
reduce() 可以作為一個高階函數(shù),用于函數(shù)的 compose。
注意:?reduce() 對于空數(shù)組是不會執(zhí)行回調函數(shù)的。
總結:
1)函數(shù)是“第一等公民”;
2)只用“表達式”,不用“語句”;全部是常量
3)沒有“副作用”;不能進行修改,導致函數(shù)不純
4)不修改狀態(tài);
5)引用透明(函數(shù)運作只靠參數(shù));在于運算什么,不在于怎么運算
純函數(shù)是指不依賴于且不改變它作用域之外的變量狀態(tài)的函數(shù);純函數(shù)的返回值只由它調用時的參數(shù)決定
Array.slice是純函數(shù),因為它沒有副作用,對于固定的輸入,輸出總是固定的;不會對原始數(shù)據進行改變;
splice將改變原始數(shù)據,因此它不是純函數(shù);
優(yōu)點:降低系統(tǒng)復雜度,有很多特性,比如可緩存性;
缺點:在不純的版本中,checkage不僅取決于age還有外部依賴的變量min。 純的checkage吧關鍵數(shù)字18硬編碼在函數(shù)內部,擴展性比較差,科利華優(yōu)化的函數(shù)式解決。(有外部的變量 可以影響到函數(shù)內部的值輸出)
函數(shù)的柯里化
傳遞給函數(shù)一部分參數(shù)來調用它,讓它返回一個函數(shù)去處理剩下的函數(shù);(方法套方法 )
柯里化之前
function add(x,y){
return x+y;
}
add(1,2) //3
柯里化之后
function addX(y){
return function(x){
return x+y
}
}
addX(2)(1) //3
事實上柯里化是一種“預加載”函數(shù)的方法,通過傳遞較少的參數(shù),得到一個一鍵記住了這些參數(shù)的新函數(shù),某種意義上講,這是一種對參數(shù)的“緩存”,是一種非常搞笑的編寫函數(shù)方法:
函數(shù)組合
純函數(shù)以及如何把它柯里化寫出的洋蔥代碼 h(g(f(x))),為了解決函數(shù)嵌套的問題,可以使用“函數(shù)組合”。讓多個函數(shù)像拼積木一樣;
幫助柯里化,美化工作;業(yè)務邏輯變清晰。
const compose = (f,g) => (x => f(g(x)));
var first = arr => arr[0];
var reverse = arr => arr[0];
var last = compose(first,reverse);
last([1,2,3,4,5]);
Pointfree編程風格
把一些對象自帶的方法轉化成純函數(shù),不要命名轉瞬即逝的中間變量。Pointfree 的本質就是使用一些通用的函數(shù),組合出各種復雜運算。上層運算不要直接操作數(shù)據,而是通過底層函數(shù)去處理。這就要求,將一些常用的操作封裝成函數(shù)。
str作為中間變量,它除了將代碼變得長一點以外毫無意義。
const f = str => str.toUpperCase().split('');
優(yōu)化后:這種編寫代碼風格能減少不必要的莫名,讓代碼保持簡潔喝通用
var toUpperCase = word => word.toUpperCase();
var split = x => (str => str.split(x));
var f = compose(split(''), toUpperCase);
f("abcd efgh");
生命式與命令式代碼