函數(shù)十分強(qiáng)大。
但我們要清楚什么是函數(shù)。它不只是一個(gè)語(yǔ)句/操作的集合。具體地說(shuō),一個(gè)函數(shù)需要一個(gè)或多個(gè)輸入(理想情況,只有一個(gè)?。┮约耙粋€(gè)輸出。
函數(shù)內(nèi)部的函數(shù)可以擁有外部變量的閉包,為稍后的訪問(wèn)記住它們。這是所有種類的編程中最重要的概念之一,而且是 FP 基礎(chǔ)中的基礎(chǔ)。
要小心匿名函數(shù),特別是箭頭函數(shù) =>。它們寫起來(lái)方便,但是將作者的成本轉(zhuǎn)嫁到了讀者身上。我們學(xué)習(xí) FP 的所有原因就是寫出可讀性更強(qiáng)的代碼,所以先不要那么快就趕這個(gè)潮流。
不要使用 this 敏感的函數(shù)。別這么干。
現(xiàn)在我們?cè)谒枷胫袑?duì) 函數(shù) 在函數(shù)式編程中意味著什么發(fā)展出了清晰而多彩的觀點(diǎn)。是時(shí)候搬弄函數(shù)以使它們協(xié)作的時(shí)候了.
萬(wàn)法歸一
一對(duì)一
說(shuō)到僅含一個(gè)參數(shù)的函數(shù),在 FP 工具箱中有另一個(gè)基本工具:一個(gè)函數(shù),它接收一個(gè)實(shí)際參數(shù)但不作任何事情并原封不動(dòng)地返回實(shí)際參數(shù)的值:
function identity(v) {
return v;
}
// 或者 ES6 => 箭頭形式
var identity =
v =>
v;
這個(gè)工具看起來(lái)如此簡(jiǎn)單,以至于很難有什么用處。但即使是簡(jiǎn)單的函數(shù)也可以在 FP 的世界中很有用處。就像人們關(guān)于表演所說(shuō)的:劇中沒(méi)有小角色,只有小演員。
例如,想象你想使用一個(gè)正則表達(dá)式分割一個(gè)字符串,但是結(jié)果數(shù)組中可能含有一些空值。要去掉這些空值,我們可以使用 JS 的 filter(..) 數(shù)組操作
var words = " Now is the time for all... ".split( /\s|\b/ );
words;
// ["","Now","is","the","time","for","all","...",""]
words.filter( identity );
// ["Now","is","the","time","for","all","..."]
因?yàn)?identity(..) 簡(jiǎn)單地返回傳遞給它的值,JS 會(huì)將每個(gè)值強(qiáng)制轉(zhuǎn)換為 true 或 false,并以此決定每個(gè)值是保留還是排除出最終的數(shù)組。
使用identity(..) 的另一個(gè)例子是在變形的地方作為默認(rèn)函數(shù):
function output(msg,formatFn = identity) {
msg = formatFn( msg );
console.log( msg );
}
function upper(txt) {
return txt.toUpperCase();
}
output( "Hello World", upper ); // HELLO WORLD
output( "Hello World" ); // Hello World
一個(gè)不變的值
特定的 API 不允許你將一個(gè)值直接傳入一個(gè)方法,但要求你傳入一個(gè)函數(shù),即使這個(gè)函數(shù)只是返回這個(gè)值。一個(gè)這樣的 API 就是 JS Promise 的 then(..) 方法:
// 不能工作:
p1.then( foo ).then( p2 ).then( bar );
// 而是:
p1.then( foo ).then( function(){ return p2; } ).then( bar );
許多人聲稱 ES6 => 箭頭函數(shù)就是 “解決方案”:
p1.then( foo ).then( () => p2 ).then( bar );
但是有更合適的
function constant(v) {
return function value(){
return v;
};
}
// 或者 ES6 => 箭頭形式
var constant =
v =>
() =>
v;
使用這個(gè)小小的工具,我們可以解決 then(..)的煩惱:
p1.then( foo ).then( constant( p2 ) ).then( bar );