The approach to creating functions that can be called in a row an unknown number of times in advance is quite standard:
- For the result to be called as a function, you need to return a function.
- To still be able to get the result, you need to redefine the valueOf , toString , any one, or all at once methods from the returned function.
- And the most important thing is that you need to store the result somewhere, which can be returned by redefined functions.
From the next answer, it is clear that you can return the original function, in which the corresponding methods are redefined. And the result is stored in the field of the function itself.
The disadvantage of this approach is that the state is globally, and by manually changing the result field, you can break down the subsequent chains.
Also, you can immediately use the internal function, and store the result, not in its field, but in a closed variable, like this:
function sum(a) { var s = a; function innerSum(b) { return sum(a + b); }; innerSum.toString = innerSum.valueOf = function() { return s; } return innerSum; } console.info(sum(1)(2)(3));
In this case, there is an assumption that functions take only one argument. If you need to expand the solution so that any function can take several arguments, you need to internally apply the reduce function to them, to apply a specific function to all parameters passed, for example:
function sum(...params) { var s = params.reduce((a, b) => a + b); function innerSum(...innerParams) { return sum(...innerParams.concat(s)); }; innerSum.toString = innerSum.valueOf = function() { return s; } return innerSum; } console.info(sum(1, 2)(3, 4)(5, 6)); console.info(sum(1)(2)(3)(4)(5)(6)); // все еще работает console.info(sum(1)(2, 3)(4, 5, 6));