摘要:為了盡可能提升互通性,已經成為函數式編程庫遵循的實際標準。與輕量級函數式編程的概念相反,它以火力全開的姿態進軍的函數式編程世界。
原文地址:Functional-Light-JS
原文作者:Kyle Simpson-《You-Dont-Know-JS》作者
JavaScript 輕量級函數式編程 附錄 C:函數式編程函數庫關于譯者:這是一個流淌著滬江血液的純粹工程:認真,是 HTML 最堅實的梁柱;分享,是 CSS 里最閃耀的一瞥;總結,是 JavaScript 中最嚴謹的邏輯。經過捶打磨練,成就了本書的中文版。本書包含了函數式編程之精髓,希望可以幫助大家在學習函數式編程的道路上走的更順暢。比心。
譯者團隊(排名不分先后):阿希、blueken、brucecham、cfanlife、dail、kyoko-df、l3ve、lilins、LittlePineapple、MatildaJin、冬青、pobusama、Cherry、蘿卜、vavd317、vivaxy、萌萌、zhouyao
如果您已經從頭到尾通讀了此書,請花一分鐘的時間停下來回顧一下從第 1 章到現在的收獲。相當漫長的一段旅程,不是嗎?希望您已經收獲了大量新知識,并用函數式的方式思考你的程序。
在本書即將完結時,我想給你提供一些關于使用官方函數式編程函數庫的快速指南。注意這并不是一個詳細的文檔,而是將你在結束“輕量級函數式編程”后進軍真正的函數式編程時應該注意的東西快速梳理一下。
如果有可能,我建議你不要做重新造輪子這樣的事情。如果你找到了一個能滿足你需求的函數式編程函數庫,那么用它就對了。只有在你實在找不到合適的庫來應對你面臨的問題時,才應該使用本書提供的輔助實用函數 —— 或者自己造輪子。
目錄在本書第 1 章曾列出了一個函數式編程庫的列表,現在我們來擴展這個列表。我們不會涉及所有的庫(它們之中有許多重復的內容),但下面這些你應該有所關注:
Ramda:通用函數式編程實用函數
Sanctuary:函數式編程類型 Ramda 伴侶
lodash/fp:通用函數式編程實用函數
functional.js:通用函數式編程實用函數
Immutable:不可變數據結構
Mori:(受到 ClojureScript 啟發)不可變數據結構
Seamless-Immutable:不可變數據助手
tranducers-js:數據轉換器
monet.js:Monad 類型
上面的列表只列出了所有函數式編程庫的一小部分,并不是說沒有在列表中列出的庫就不好,也不是說列表中列出的就是最佳選擇,總之這只是 JavaScript 函數式編程世界中的一瞥。您可以前往這里查看更完整的函數式編程資源。
Fantasy Land(又名 FL)是函數式編程世界中十分重要的學習資源之一,與其說它是一個庫,不如說它是一本百科全書。
Fantasy Land 不是一份為初學者準備的輕量級讀物,而是一個完整而詳細的 JavaScript 函數式編程路線圖。為了盡可能提升互通性,FL 已經成為 JavaScript 函數式編程庫遵循的實際標準。
Fantasy Land 與“輕量級函數式編程”的概念相反,它以火力全開的姿態進軍 JavaScript 的函數式編程世界。也就是說,當你的能力超越本書時,FL 將會成為你接下來前進的方向。我建議您將其保存在收藏夾中,并在您使用本書的概念進行至少 6 個月的實戰練習之后再回來。
Ramda (0.23.0)摘自 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/fp (4.17.4)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 世界時的堅實后盾。
Mori (0.3.2)在第 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官網:https://www.ikcamp.com
訪問官網更快閱讀全部免費分享課程:
《iKcamp出品|全網最新|微信小程序|基于最新版1.0開發者工具之初中級培訓教程分享》
《iKcamp出品|基于Koa2搭建Node.js實戰項目教程》
包含:文章、視頻、源代碼
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92391.html
摘要:我稱之為輕量級函數式編程。序眾所周知,我是一個函數式編程迷。函數式編程有很多種定義。本書是你開啟函數式編程旅途的絕佳起點。事實上,已經有很多從頭到尾正確的方式介紹函數式編程的書了。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 譯者團隊(排名不分先后):阿希、blueken、brucecham、...
摘要:所以我覺得函數式編程領域更像學者的領域。函數式編程的原則是完善的,經過了深入的研究和審查,并且可以被驗證。函數式編程是編寫可讀代碼的最有效工具之一可能還有其他。我知道很多函數式編程編程者會認為形式主義本身有助于學習。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著滬江血液...
摘要:就像我寫書的過程一樣,每個開發者在學習函數式編程的旅程中都會經歷這個部分。類型在函數式編程中有一個巨大的興趣領域類型論,本書基本上完全遠離了該領域。在函數式編程中,像這樣涵蓋是很普遍的。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著滬江血液的純粹工程:認真,是 HTML...
摘要:譯者團隊排名不分先后阿希冬青蘿卜萌萌輕量級函數式編程附錄下組合柯里化這一步是最棘手的。該片段中的組合函數被稱為,而不是。上一章翻譯連載附錄上輕量級函數式編程你不知道的姊妹篇原創新書移動前端高效開發實戰已在亞馬遜京東當當開售。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著...
摘要:我不會把嚴格的稱為輕量級函數式編程,它更像是一個頂級的技巧。實際上,我認為這是你掌握了輕量級函數式編程后可以做的最好的例證之一。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關于譯者:這是一個流淌著滬江血液的純粹工程:認真,是 HTML 最堅實的梁柱;分享,是 CSS 里最閃耀的一瞥;總結,是 ...
閱讀 2922·2021-11-24 09:39
閱讀 3599·2021-11-22 13:54
閱讀 3409·2021-11-16 11:45
閱讀 2432·2021-09-09 09:33
閱讀 3194·2019-08-30 15:55
閱讀 1290·2019-08-29 15:40
閱讀 920·2019-08-29 15:19
閱讀 3396·2019-08-29 15:14