返回課程

帶任意數量括號的加總

重要性:2

撰寫函式 sum,其運作方式如下

sum(1)(2) == 3; // 1 + 2
sum(1)(2)(3) == 6; // 1 + 2 + 3
sum(5)(-1)(2) == 6
sum(6)(-1)(-2)(-3) == 0
sum(0)(1)(2)(3)(4)(5) == 15

P.S. 提示:你可能需要為函式設定自訂物件轉換為原始值。

開啟包含測試的沙盒。

  1. 無論如何,要讓整體運作,sum 的結果必須是函式。
  2. 該函式必須在呼叫之間記住目前的數值。
  3. 根據任務,函數在用於 == 時必須變成數字。函數是物件,因此轉換會如 物件轉換為原始值 章節中所述發生,而且我們可以提供傳回數字的自己的方法。

現在的程式碼

function sum(a) {

  let currentSum = a;

  function f(b) {
    currentSum += b;
    return f;
  }

  f.toString = function() {
    return currentSum;
  };

  return f;
}

alert( sum(1)(2) ); // 3
alert( sum(5)(-1)(2) ); // 6
alert( sum(6)(-1)(-2)(-3) ); // 0
alert( sum(0)(1)(2)(3)(4)(5) ); // 15

請注意 sum 函數實際上只執行一次。它傳回函數 f

然後,在每個後續呼叫中,f 會將其參數新增至總和 currentSum,並傳回其本身。

f 的最後一行沒有遞迴。

遞迴看起來像這樣

function f(b) {
  currentSum += b;
  return f(); // <-- recursive call
}

而在我們的案例中,我們只傳回函數,而不會呼叫它

function f(b) {
  currentSum += b;
  return f; // <-- does not call itself, returns itself
}

這個 f 將會用於下一個呼叫,再次傳回其本身,次數視需要而定。然後,當用作數字或字串時,toString 會傳回 currentSum。我們也可以在此使用 Symbol.toPrimitivevalueOf 來進行轉換。

在沙盒中開啟包含測試的解答。