Currying
Currying is an advanced technique of working with functions. It’s used not only in JavaScript, but in other languages as well.
Currying is a transformation of functions that translates a function from callable as
f(a, b, c)
into callable asf(a)(b)(c)
.Currying doesn’t call a function. It just transforms it.
範例 1:
說明:(1) 資料傳遞方式、(2) 參數 x 和 y 值變化
- 命名 add5 = makeAdder(5),函式 makeAdder(x)的參數 x,固定代入
5 後, 繼續執行inner func-return function(y)。
但 inner func的return function(y) 只有參數 y,沒有 x,所以只會計算 x。 - 測試 console.log(“add5(0)”,add5(0)):
可得知函式 add5內的參數為y,得知完整函式和參數 add5(y)。
// 得出 5+0=5 - 執行 console.log(“add5(2)”,add5(2)):
// 得出 5+2=7
範例 2 (承範例 1 ):
嘗試寫一組 add 函式,分別使 add(a, b) 和 add(a)(b) 回傳同樣結果,例如:
add(1, 2); // 3
add(1)(2); // 3
- 以 Currying 觀念函式為基礎,建立 add 函式。
- Currying 觀念函式內部新增 if 條件式的 inner function:
if(x, y){return x + y}。 - 最外層 add 函式的參數由單一個 x,改為 2 個參數 (x, y):
add(x) => add(x, y)
範例 2 出現 Bug:add(2, 0) !== add(2)(0)
console.log(“add(2, 0)”, add(2, 0))
console.log(“add(2)(0)”, add(2)(0))
Debug:流程斷點Step1、Step2 設console.log,測試:
- 若代入add(-1, 1)、add(0, 1)等參數,皆正常。
- 唯獨若代入add(2, 0),發現流程不會經過 Step 1 的 if 條件式,
表示 if (x, y)這種寫法 JavaScript 無法讀取其中的 y。
Bug 原因:
參數 0 代入if(x, y),若 if 條件式內有 0,被 JavaScript 型別轉換成 False。
因 Javascript 為弱型別語言,即型別之間比較會強制轉型。
修改方式:
將 if 條件式修改為更精確表達,將 if(x, y) 改為 if((typeof x ===”number”) && (typeof y ===”number”)),強制限定參數 x 和 y 的型別必須同時為 number。
修改後: