Я решил добавить еще одно решение для удовольствия, используя некоторые функции ES6:
"use strict";
const add = (function add() {
"use strict";
let
sum = [this, ...arguments].reduce((a, b) => a + b),
chain = add.bind(sum);
chain[Symbol.toPrimitive] = hint => sum;
return chain;
}).bind(0);
strict mode
необходимо только для поддержки использования const
и let
, в противном случае вы можете просто выполните его как:
var add = (function add() {
var
sum = [this, ...arguments].reduce((a, b) => a + b),
chain = add.bind(sum);
chain[Symbol.toPrimitive] = hint => sum;
return chain;
}).bind(0);
Ниже приведена демоверсия. Обратите внимание, что это поддерживается только в браузерах, совместимых с ES6:
"use strict";
/* add function */
const add = (function add() {
"use strict";
let
sum = [this, ...arguments].reduce((a, b) => a + b),
chain = add.bind(sum);
chain[Symbol.toPrimitive] = hint => sum;
return chain;
}).bind(0);
/* tests */
print(`add(1, 2) = ${add(1, 2)}`);
print(`add(1)(2) = ${add(1)(2)}`);
/* even cooler stuff */
print(`add(1, 2)(3) = ${add(1, 2)(3)}`);
print(`add(1, 2, 3)(4, 5)(6) = ${add(1, 2, 3)(4, 5)(6)}`);
/* retains expected state */
var add7 = add(7);
print('var add7 = add(7)');
print(`add7(3) = ${add7(3)}`);
print(`add7(8) = ${add7(8)}`);
/* ignore this */
function print(value) {
var div = document.createElement('div');
div.textContent = value;
document.body.appendChild(div);
}