Сума з довільною кількістю дужок
Напишіть функцію 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. Підказка: вам може знадобитися налаштувати кастомний об’єкт, щоб конвертувати примітиви для вашої функції.
- Загалом, для того щоб все працювало хоч як-небудь, результат
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
фактично працює лише раз. Вона повертає функцію f
.
Потім, на кожному наступному виклику, f
додає свій параметр до суми currentSum
, і повертає себе.
В останньому рядку f
немає ніякої рекурсії.
Ось як рекурсія виглядає:
function f(b) {
currentSum += b;
return f(); // <-- рекурсивний виклик
}
А в нашому випадку ми просто повертаємо цю функцію, не викликаючи її:
function f(b) {
currentSum += b;
return f; // <-- не викликає себе, повертає себе
}
Ця функція f
буде використовуватися в наступному виклику і знову поверне себе стільки разів, скільки буде потрібно. Потім, при використанні функції як числа або рядка – метод toString
поверне currentSum
. Тут ми також можемо використовувати Symbol.toPrimitive
або valueOf
для конверсії.