點燈坊

失くすものさえない今が強くなるチャンスよ

使用 bind() 將 Static Method 轉成 Free Function

Sam Xiao's Avatar 2020-07-27

ECMAScript 提供了不少原生 Static Method,但我們也可使用 Ramd 的 bind() 將其轉成 Free Function 使其更符合 FP 風格。

Version

Ramda 0.27.1

Promise

Promise.resolve(1) // ?

Promise.resolve() 為 static method,可建立 Fulfilled Promise。

bind000

Object Destructuring

let { resolve } = Promise

resolve(1) // ?

若我們想將 Promise.resolve() 轉成 free function,理論上我們可使用 Object Destructuring 抽出 resolve()

bind001

但實際執行卻出現錯誤,why not ?

call()

let { resolve } = Promise

resolve.call(Promise, 1) // ?

因為 Promise.resolve() 內部使用了 this,抽成 free function 後,this 就成了 undefined,因此我們必須將 this 找回。

可將 Promise 傳入 .call() 重新定義 this

bind002

bind()

let { resolve } = Promise

resolve.bind(Promise)(1) // ?

也可將 Promise 傳入 .bind() 回傳新 function。

bind003

Ramda

import { bind } from 'ramda'

let resolve = bind(Promise.resolve, Promise)

resolve(1) // ?

.call().bind() 雖然可行,最後還得傳入 Promise,顯然並不好用。

最簡單方式是使用 Ramda 的 bind()Promise.resolve() 轉成 free function。

bind()
(* → *) → {*} → (* → *)
將 static method 轉成 free function

bind004

Conclusion

  • 實務上很多都使用 static method,如 Promise.resolve()axios.get() … 等,使用 object destructuring 並無法百分之百保證能轉成 free function,但 Ramda 的 bind() 可保證成功

Reference

Ramda, bind()
MDN, Function.prototype.call()
MDN, Function.prototype.bind()