關於譯者:這是一個流淌着滬江血液的純粹工程:認真,是 HTML 最堅實的樑柱;分享,是 CSS 裏最閃耀的一瞥;總結,是 JavaScript 中最嚴謹的邏輯。通過捶打磨練,成就了本書的中文版。本書包含了函數式編程之精髓,但願能夠幫助你們在學習函數式編程的道路上走的更順暢。比心。前端
譯者團隊(排名不分前後):阿希、blueken、brucecham、cfanlife、dail、kyoko-df、l3ve、lilins、LittlePineapple、MatildaJin、冬青、pobusama、Cherry、蘿蔔、vavd317、vivaxy、萌萌、zhouyaonode
若是您已經從頭至尾通讀了此書,請花一分鐘的時間停下來回顧一下從第 1 章到如今的收穫。至關漫長的一段旅程,不是嗎?但願您已經收穫了大量新知識,並用函數式的方式思考你的程序。git
在本書即將完結時,我想給你提供一些關於使用官方函數式編程函數庫的快速指南。注意這並非一個詳細的文檔,而是將你在結束「輕量級函數式編程」後進軍真正的函數式編程時應該注意的東西快速梳理一下。程序員
若是有可能,我建議你不要作從新造輪子這樣的事情。若是你找到了一個能知足你需求的函數式編程函數庫,那麼用它就對了。只有在你實在找不到合適的庫來應對你面臨的問題時,才應該使用本書提供的輔助實用函數 —— 或者本身造輪子。github
在本書第 1 章曾列出了一個函數式編程庫的列表,如今咱們來擴展這個列表。咱們不會涉及全部的庫(它們之中有許多重複的內容),但下面這些你應該有所關注:編程
上面的列表只列出了全部函數式編程庫的一小部分,並非說沒有在列表中列出的庫就很差,也不是說列表中列出的就是最佳選擇,總之這只是 JavaScript 函數式編程世界中的一瞥。您能夠前往這裏查看更完整的函數式編程資源。小程序
Fantasy Land(又名 FL)是函數式編程世界中十分重要的學習資源之一,與其說它是一個庫,不如說它是一本百科全書。微信小程序
Fantasy Land 不是一份爲初學者準備的輕量級讀物,而是一個完整而詳細的 JavaScript 函數式編程路線圖。爲了儘量提高互通性,FL 已經成爲 JavaScript 函數式編程庫遵循的實際標準。數組
Fantasy Land 與「輕量級函數式編程」的概念相反,它以火力全開的姿態進軍 JavaScript 的函數式編程世界。也就是說,當你的能力超越本書時,FL 將會成爲你接下來前進的方向。我建議您將其保存在收藏夾中,並在您使用本書的概念進行至少 6 個月的實戰練習以後再回來。微信
摘自 Ramda 文檔:
Ramda 函數自動地被柯里化。
Ramda 函數的參數通過優化,更便於柯里化。須要被操做的數據每每放在最後提供。
我認爲合理的設計是 Ramda 的優點之一。值得注意的是,Ramda 的柯里化形式(彷佛大多數的庫都是這種形式)是咱們在第 3 章中討論過的「鬆散柯里化」。
第 3 章的最後一個例子 —— 咱們定義無值(point-free)工具函數 printIf()
—— 能夠在 Ramda 中這樣實現:
function output(msg) {
console.log( msg );
}
function isShortEnough(str) {
return str.length <= 5;
}
var isLongEnough = R.complement( isShortEnough );
var printIf = R.partial( R.flip( R.when ), [output] );
var msg1 = "Hello";
var msg2 = msg1 + " World";
printIf( isShortEnough, msg1 ); // Hello
printIf( isShortEnough, msg2 );
printIf( isLongEnough, msg1 );
printIf( isLongEnough, msg2 ); // Hello World
複製代碼
與咱們在第 3 章中的實現相比有幾處不一樣:
咱們使用 R.complement(..)
而不是 not(..)
在 isShortEnough(..)
周圍新建一個否認函數 isLongEnough(..)
。
使用 R.flip(..)
而不是 reverseArgs(..)
函數,值得一提的是,R.flip(..)
僅交換頭兩個參數,而 reverseArgs(..)
會將全部參數反向。在這種情景下,flip(..)
更加方便,因此咱們再也不須要使用 partialRight(..)
或其餘投機取巧的方式進行處理。
R.partial(..)
全部的後續參數以單個數組的形式存在。
由於 Ramda 使用鬆散柯里化,所以咱們不須要使用 R.uncurryN(..)
來得到一個包含全部參數的 printIf(..)
。若是咱們這樣作了,就至關於使用 R.uncurryN(2, ..)
包裹 R.partial(..)
進行調用,這是徹底沒有必要的。
Ramda 是一個受歡迎的、功能強大的庫。若是你想要在你的代碼中實踐 FP,從 Ramda 開始是個不錯的選擇。
Lodash 是整個 JS 生態系統中最受歡迎的庫。Lodash 團隊發佈了一個「FP 友好」的 API 版本 —— "lodash/fp"。
在第 8 章中,咱們討論了合併獨立列表操做(map(..)
、filter(..)
以及 reduce(..)
)。使用「lodash/fp」時,你能夠這樣作:
var sum = (x,y) => x + y;
var double = x => x * 2;
var isOdd = x => x % 2 == 1;
fp.compose( [
fp.reduce( sum )( 0 ),
fp.map( double ),
fp.filter( isOdd )
] )
( [1,2,3,4,5] ); // 18
複製代碼
與咱們所熟知的 _.
命名空間前綴不一樣,「lodash/fp」將 fp.
定義爲其命名空間前綴。我發現一個頗有用的區別,就是 fp.
比 _.
更容易識別。
注意 fp.compose(..)
(在常規 lodash 版本中又名 _.flowRight(..)
)接受一個函數數組,而不是獨立的函數做爲參數。
lodash 擁有良好的穩定性、普遍的社區支持以及優秀的性能,是你探索 FP 世界時的堅實後盾。
在第 6 章中,咱們已經快速瀏覽了一下 Immutable.js 庫,該庫多是最廣爲人知的不可變數據結構庫了。
讓咱們來看一下另外一個流行的庫:Mori。Mori 設計了一套不同凡響(從表面上看更像函數式編程)的 API:它使用獨立的函數而不直接在值上操做。
var state = mori.vector( 1, 2, 3, 4 );
var newState = mori.assoc(
mori.into( state, Array.from( {length: 39} ) ),
42,
"meaning of life"
);
state === newState; // false
mori.get( state, 2 ); // 3
mori.get( state, 42 ); // undefined
mori.get( newState, 2 ); // 3
mori.get( newState, 42 ); // "meaning of life"
mori.toJs( newState ).slice( 1, 3 ); // [2,3]
複製代碼
這是一個指出關於 Mori 的一些有趣的事情的例子:
使用 vector
而不是 list
(你可能會想用的),主要是由於文檔說它的行爲更像 JavaScript 中的數組。
不能像在操做原生 JavaScript 數組那樣在任意位置設置值,在 vector 結構中,這將會拋出異常。所以咱們必須使用 mori.into(..)
,傳入一個合適長度的數組來擴展 vector 的長度。在上例中,vector 有 43 個可用位置(4 + 39),因此咱們能夠在最後一個位置(索引爲 42)上寫入 "meaning of life"
這個值。
使用 mori.into(..)
建立一個較大的 vector,再用 mor.assoc(..)
根據這個 vector 建立另外一個 vector 的作法聽起來效率低下。可是,不可變數據結構的好處在於數據不會進行克隆,每次「改變」發生,新的數據結構只會追蹤其與舊數據結構的不一樣之處。
Mori 受到 ClojureScript 極大的啓發。若是您有 ClojureScript 編程經驗,那您應該對 Mori 的 API 感到很是熟悉。因爲我沒有這種編程經驗,所以我感受 Mori 中的方法名有點奇怪。
但相比於在數據上直接調用方法,我真的很喜歡調用獨立方法這樣的設計。Mori 還有一些自動返回原生 JavaScript 數組的方法,用起來很是方便。
JavaScript 不是做爲函數式編程語言來特別設計的。不過其自身的確擁有不少對函數式編程很是友好基礎語法(例如可做爲變量的函數、閉包等)。本章說起的庫將使你更方便的進行函數式編程。
有了本書中函數式編程概念的武裝,相信你已經準備好開始處理現實世界的代碼了。找一個優秀的函數式編程庫來用,而後練習,練習,再練習。
就是這樣了。我已經將我目前所知道的知識分享給你了。我在此正式認證您爲「JavaScript 輕量級函數式編程」程序員!好了,是時候結束咱們一塊兒學習 FP 這部分的「章節」了,但個人學習之旅還將繼續。我但願,你也是!
**【上一章】翻譯連載 | 附錄 B: 謙虛的 Monad-《JavaScript輕量級函數式編程》 |《你不知道的JS》姊妹篇 **
iKcamp原創新書《移動Web前端高效開發實戰》已在亞馬遜、京東、噹噹開售。
iKcamp官網:www.ikcamp.com 訪問官網更快閱讀所有免費分享課程: 《iKcamp出品|全網最新|微信小程序|基於最新版1.0開發者工具之初中級培訓教程分享》 《iKcamp出品|基於Koa2搭建Node.js實戰項目教程》 包含:文章、視頻、源代碼
iKcamp新課程推出啦~~~~~開始免費連載啦~每週2更共11堂iKcamp課|基於Koa2搭建Node.js實戰項目教學(含視頻)| 課程大綱介紹
2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!