函數(shù)式編程(高階函數(shù))一般是用于寫幫助庫淹朋;插件直接面向?qū)ο?/p>
1.point free 概念:無值操作
2.應(yīng)用:取得系統(tǒng)api轉(zhuǎn)純,也就是無值操作姿骏,方便組合
Io是處理不純
Monad是處理不存
范疇論函數(shù)式編程和是范疇論的數(shù)學(xué)分支含懊,所有概念體系都可以抽象出一個個范疇腻脏;彼此之間存在某種關(guān)系概念、事物冯丙、對象等肉瓦,都構(gòu)成范疇。箭頭表示范疇成員之間的關(guān)系胃惜,正式名稱“態(tài)射”泞莉。同一個范疇的所有成員就是不同狀態(tài)的“變形”。通過“態(tài)射”船殉,一個成員可以變形到另一個成員鲫趁。
所有成員是一個集合;變形關(guān)系是函數(shù)
將復(fù)雜的函數(shù)符 合成簡單函數(shù)(計算理論利虫、遞歸論或者拉姆達驗算)挨厚。運算過程盡量寫成一系列嵌套的函數(shù)調(diào)用(抽象)
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);
}
輸出結(jié)果:2,3,4,5
map() 方法返回一個新數(shù)組咨油,數(shù)組中的元素為原始數(shù)組元素調(diào)用函數(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);
}
輸出結(jié)果:125
reduce() 方法接收一個函數(shù)作為累加器棉胀,數(shù)組中的每個值(從左到右)開始縮減法瑟,最終計算為一個值。
reduce() 可以作為一個高階函數(shù)唁奢,用于函數(shù)的 compose霎挟。
注意:?reduce() 對于空數(shù)組是不會執(zhí)行回調(diào)函數(shù)的。
總結(jié):
1)函數(shù)是“第一等公民”麻掸;
2)只用“表達式”酥夭,不用“語句”;全部是常量
3)沒有“副作用”脊奋;不能進行修改熬北,導(dǎo)致函數(shù)不純
4)不修改狀態(tài);
5)引用透明(函數(shù)運作只靠參數(shù))诚隙;在于運算什么讶隐,不在于怎么運算
純函數(shù)是指不依賴于且不改變它作用域之外的變量狀態(tài)的函數(shù);純函數(shù)的返回值只由它調(diào)用時的參數(shù)決定
Array.slice是純函數(shù)久又,因為它沒有副作用巫延,對于固定的輸入,輸出總是固定的地消;不會對原始數(shù)據(jù)進行改變炉峰;
splice將改變原始數(shù)據(jù),因此它不是純函數(shù)脉执;
優(yōu)點:降低系統(tǒng)復(fù)雜度疼阔,有很多特性,比如可緩存性适瓦;
缺點:在不純的版本中竿开,checkage不僅取決于age還有外部依賴的變量min谱仪。 純的checkage吧關(guān)鍵數(shù)字18硬編碼在函數(shù)內(nèi)部,擴展性比較差否彩,科利華優(yōu)化的函數(shù)式解決疯攒。(有外部的變量 可以影響到函數(shù)內(nèi)部的值輸出)
函數(shù)的柯里化
傳遞給函數(shù)一部分參數(shù)來調(diào)用它,讓它返回一個函數(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
事實上柯里化是一種“預(yù)加載”函數(shù)的方法敬尺,通過傳遞較少的參數(shù),得到一個一鍵記住了這些參數(shù)的新函數(shù)贴浙,某種意義上講砂吞,這是一種對參數(shù)的“緩存”,是一種非常搞笑的編寫函數(shù)方法:
函數(shù)組合
純函數(shù)以及如何把它柯里化寫出的洋蔥代碼 h(g(f(x))),為了解決函數(shù)嵌套的問題崎溃,可以使用“函數(shù)組合”蜻直。讓多個函數(shù)像拼積木一樣;
幫助柯里化袁串,美化工作概而;業(yè)務(wù)邏輯變清晰。
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編程風(fēng)格
把一些對象自帶的方法轉(zhuǎn)化成純函數(shù)囱修,不要命名轉(zhuǎn)瞬即逝的中間變量赎瑰。Pointfree 的本質(zhì)就是使用一些通用的函數(shù),組合出各種復(fù)雜運算破镰。上層運算不要直接操作數(shù)據(jù)餐曼,而是通過底層函數(shù)去處理。這就要求鲜漩,將一些常用的操作封裝成函數(shù)源譬。
str作為中間變量,它除了將代碼變得長一點以外毫無意義宇整。
const f = str => str.toUpperCase().split('');
優(yōu)化后:這種編寫代碼風(fēng)格能減少不必要的莫名瓶佳,讓代碼保持簡潔喝通用
var toUpperCase = word => word.toUpperCase();
var split = x => (str => str.split(x));
var f = compose(split(''), toUpperCase);
f("abcd efgh");
生命式與命令式代碼