用 bind 實現 currying

currying 這個技巧在 js 裡面可以省去一些工,
也讓程式碼看起還好像乾淨一些,但如果還是覺得不夠白話。

假設,我們有個要組合網址的需求
function simpleURL(p,d,path){ return `${p}://${d}/${path}` }
var paths = ['aa','bb','cc']
// compress - step 1
var urls = paths.map((path) => {
var protocol = 'https'
var domain = 'www.google.com.tw'
var setFunWithVariables = simpleURL.bind(null, protocol, domain)
return setFunWithVariables(path)
})
// ["https://www.google.com.tw/aa", "https://www.google.com.tw/bb", "https://www.google.com.tw/cc"]

我們可以盡量縮寫,把定義直接填入參數中,但是這樣就已經有點難懂了
var urls = paths.map((path) => {
return simpleURL.bind(null, 'https', 'www.google.com.tw')(path)
})

再用 es6 寫法,省去 return
var urls = paths.map((val) => simpleURL.bind(null, 'https', 'www.google.com.tw')(val) )

但還可以再精簡... 因為用 bind 可以把 function 改寫成為一個已經帶入參數的 function 
var bindFn = simpleURL.bind( null, 'http', 'www.google.com.tw')
可以看成以下
var bindFn = function(path) {
  return simpleURL('http', 'www.google.com.tw', path)
}

var bindFn = function(path) {
return simpleURL('http', 'www.google.com.tw', path)
}
var urls = paths.map(bindFn)

最後就可以改寫成這樣
var urls = paths.map(simpleURL.bind(null, 'https', 'www.google.com.tw'))

看起來很乾淨,效能測起來也沒有不同,就是一種求簡短不白話的寫法 ha。

留言