remeda piped 之 reference 問題
remeda 提供了一個 piped
function,可以更方便的組織函數,不過我在使用時遇到了一個問題。
甚麼是 Remeda
不知道甚麼是 Remeda 的朋友,可以參考我之前的文章:好 pipe 不用嗎?藉由 remeda 讓程式碼更簡潔彈性吧!
考慮以下程式:
ts
const getList1 = R.piped(
R.reduce((acc, item) => acc, [])
)
function getList2(list) {
return R.pipe(
list,
R.reduce((acc, item) => acc, [])
)
}
乍看之下,這兩個函數效果相同,但實際上 getList1
有一個大坑。
大家猜猜看是甚麼坑?
提示:不是 remeda
的問題,是 JS 本身的特性。
還沒看出問題的朋友不用擔心,實際跑跑看就知道了。( ´ ▽ ` )ノ
結果
getList1
回傳的結果都是同一個記憶體位置,也就是說,每次呼叫 getList1
都會得到同一個陣列。Σ(ˊДˋ;)
至於為甚麼,讓我們換個寫法就能理解了,getList1
的寫法等校於:
ts
const initValue = []
const getList1 = R.piped(
R.reduce((acc, item) => acc, initValue)
)
問題在於 getList1
的初始值變成一個全域變數,所以每次呼叫 getList1
都會得到同一個陣列。
getList2
由於初始值的 []
在 function 呼叫時才初始化,所以沒有此問題。
大家在使用 piped
時,要特別注意這個問題,以免埋了一個巨大的地雷喔。(´,,•ω•,,)
TIP
補充一個 remeda
開發者的討論,有興趣的人可以一起參與討論。੭ ˙ᗜ˙ )੭
總結 🐟
- 使用
piped
要特別注意可能的 reference 問題。 - 這個不是
remeda
的問題,而是 JS 本身的特性。