renovations
This commit is contained in:
parent
c7d4c7e3ff
commit
e1948130f6
170 changed files with 1496 additions and 1161 deletions
|
@ -0,0 +1,59 @@
|
|||
# Подсказка
|
||||
|
||||
Чтобы `sum(1)`, а также `sum(1)(2)` можно было вызвать новыми скобками -- результатом `sum` должна быть функция.
|
||||
|
||||
Но эта функция также должна уметь превращаться в число. Для этого нужно дать ей соответствующий `valueOf`. А если мы хотим, чтобы и в строковом контексте она вела себя так же -- то `toString`.
|
||||
|
||||
# Решение
|
||||
|
||||
Функция, которая возвращается `sum`, должна накапливать значение при каждом вызове.
|
||||
|
||||
Удобнее всего хранить его в замыкании, в переменной `currentSum`. Каждый вызов прибавляет к ней очередное значение:
|
||||
|
||||
```js
|
||||
//+ run
|
||||
function sum(a) {
|
||||
|
||||
var 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` нет рекурсивного вызова.**
|
||||
|
||||
Вот так была бы рекурсия:
|
||||
|
||||
```js
|
||||
function f(b) {
|
||||
currentSum += b;
|
||||
return f(); // <-- подвызов
|
||||
}
|
||||
```
|
||||
|
||||
А в нашем случае, мы просто возвращаем саму функцию, ничего не вызывая.
|
||||
|
||||
```js
|
||||
function f(b) {
|
||||
currentSum += b;
|
||||
return f; // <-- не вызывает сама себя, а возвращает ссылку на себя
|
||||
}
|
||||
```
|
||||
|
||||
Эта `f` используется при следующем вызове, опять возвратит себя, и так сколько нужно раз. Затем, при использовании в строчном или численном контексте -- сработает `toString`, который вернет текущую сумму `currentSum`.
|
Loading…
Add table
Add a link
Reference in a new issue