括弧の量が任意の合計
重要度: 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
ヒント: 関数用にカスタムオブジェクトをプリミティブに変換する必要がある場合があります。
- とにかくすべてが機能するために、
sum
の結果は関数でなければなりません。 - その関数は、呼び出し間で現在の値をメモリに保持する必要があります。
- タスクによると、関数は
==
で使用されると数値にならなければなりません。関数はオブジェクトなので、変換はオブジェクトからプリミティブに変換する章で説明されているとおりに行われ、数値を返す独自のメソッドを提供できます。
これでコード
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
関数は実際には1回だけ機能することに注意してください。関数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.toPrimitive
またはvalueOf
を使用することもできます。