iT邦幫忙

2022 iThome 鐵人賽

DAY 28
0
Modern Web

致 JavaScript 開發者的 Functional Programming 新手指南系列 第 28

Day 28 :第三方函式庫 (3):從 Ramda.js 深入了解 JavaScript

  • 分享至 

  • xImage
  •  

與 Lodash.js 類似, Ramda.js 是一個專門以 FP 模式設計出來的函式庫,與 Lodash 不同的是,Ramda 所提供的函式預設就已經柯里化了,這讓開發者可以更用彈性的去使用這個函式庫。

如果我們要在自己程式碼中引入 Ramda.js ,可以使用以下方式:

$ npm install ramda

透過套件管理工具 NPM 進行安裝後,再透過 ES Module 的方式將函式庫引入使用:

import * as R from "ramda";

接著我們就可以透過 R 變數進行 Ramda 方法的取用了!

當然,Ramda 也可以透過 CDN 的方式引入:

<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

透過 CDN 引入的 Ramda.js,同樣使用 R 變數來進行方法的取用,那麼就讓我們來看看 Ramda 提供了什麽樣的方法吧!

Ramda 方好用法分享

R.type 檢查資料型別:

相較於 Lodash is 系列開頭的方法,我認為 Ramda 的 R.type() 方法更加的泛用,這樣就不需要再花時間找指定型別的相對應方法了:

R.type({}); //=> "Object"
R.type(1); //=> "Number"
R.type(false); //=> "Boolean"
R.type('s'); //=> "String"
R.type(null); //=> "Null"
R.type([]); //=> "Array"
R.type(/[A-z]/); //=> "RegExp"
R.type(new Date); //=> "Date"

R.flip 翻轉參數順序:

在柯里化的過程中,我們會發現參數的順序會決定我們要固定住哪個參數,問題來了,萬一在某些狀況下我們想固定的參數是不一樣的怎麼辦?

在 Ramda 中,我們可以使用 R.flip() 將函式中的第一個參數及第二個參數的位置翻轉過來,這樣我們就可以依照情境的不同,選擇自己要固定第一個還是第二個參數:

const mergeThree = (a, b, c) => [].concat(a, b, c);

mergeThree(1, 2, 3); //=> [1, 2, 3]

R.flip(mergeThree)(1, 2, 3); //=> [2, 1, 3]

**R.flatten 攤平陣列結構:**

在 FP 中,我們仰賴資料層級結構一致的資料,這樣才可以進行重複的運算,與 Lodash 一樣,Ramda 也提供了 flatten() 進行深層的陣列結構攤平:

R.flatten([[{a: 1}], 2, 3, 4, 5, 6, [7, 8, [9, [10, 11], 12]]]);
//=> [{ a: 1}, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

R.intersection 篩選兩陣列之相等值:

在 Ramda 中,我們可以透過 intersection() 方法,將兩陣列中的相同值進行比對後,篩選出值相等的內容回傳至新陣列:

R.intersection([{a: 1, b: { c: 1}},2,3,4], [{a: 1, b: { c: 1}}, 7,6,5,4,3]);
//=> [{"a": 1, "b": {"c": 1}}, 3, 4]

此時我們就會獲得一個全新的陣列,其中帶有兩陣列「值相等」的內容。

看到這你可能會發現:「咦?兩陣列中的物件,正常來說不是不應該相等嗎?」

為什麼換到 Ramda 中,物件傳參考的特性怎麼就不一定適用了?

這裡可以發現另外一個 Ramda 與 Lodash 最大的不同在於:Ramda 重視「值」的本身與貼近 FP 設計模式的實作,所以在這個方法中我們才會獲得兩陣列中「值相等」的物件。

Ramda v.s Lodash?

不曉得有沒有人跟我一樣,在一開始看到這兩個函式庫所提供的方法時,腦袋跳出三個問號:「為什麼 Lodash 跟 Ramda 這麼像?」

儘管這兩個函式庫「看起來」真的很相似,認真看下來會發現他們的訴求還是有所差異,舉例來說,在 Lodash 中提供大量使用二分法的篩選方法,這讓前端開開發者在使用純函式進行程式碼管理之餘,還能使用效能較佳的方法進行演算,這一點是 Ramda 比較沒有做到的。

在 stack overflow 社群中,也有人針對這兩個函式庫的差異提出疑問,而 Ramda 的開發者 Scott Sauyet 是這麼說的:「比起效能,Ramda 更關注簡單、乾淨的 API 設計。Ramda 認為一個函式只能做一件事,這造就了 Ram 相對簡單的介面(interface)。」

以我自己使用下來的經驗,確實如同 Scott Sauyet 所述,Ramda 所提供的函式更加簡潔,也比 Lodash 更貼近了 FP 設計模式,所以可以看到更多高階函式與複合函式進階應用。

我認為這有好處也有壞處,好處在於:對 FP 熟悉的開發者來說,有更多既有的工具可以重複組合使用,壞處也同時產生:對 FP 不熟,或是沒那麼多經驗的開發者來說,Ramda.js 有點過於彈性了,缺凡語意的函式往往讓程式碼的易讀性降低,撇除這一點,Ramda 真的是一個很值得開發者學習及使用的函式庫。

對我來說 Lodash 更新手友善了一點,大部分的方法都很語意化,實務中遇到一些難解的邏輯運算時,Lodash 是一個很好的教科書,沒事翻一翻也會有一些靈感。

相比下來,Ramda 對我來說有點進階,也許是對 FP 了解不夠深入,許多 Ramda 方法比較難讓我聯想到實務上可以怎麼使用,甚至有些方法可以透過 JavaScript 的運算子所做到,多引入一個方法反而不那麼直覺。

Ramda 的開發者 Scott Sauyet 也提到:「這兩個函式庫沒有誰比較好,端看開發者的需求而定。」

簡單聊完了這兩個函式庫,這個系列的文章也差不多到了尾聲,然而 FP 的學問深的很,還有一些我們所沒有提及的內容,就讓我們在下一個章節做個小總結吧!

參考資料:

  1. Ramda.js
  2. Differences between Lodash and Ramda

上一篇
Day 27 :第三方函式庫(2):從 Lodash.js 深入了解 JavaScript
下一篇
Day 29 :總結 & 那些未完待續的 FP
系列文
致 JavaScript 開發者的 Functional Programming 新手指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言