This question has already been answered:

Good day. Very interested in this question: how to create a function through a closure which, for example, adds numbers like this:

function sum(a){ return function(b){ return a + b; } } console.log(sum(5)(6)); //11 

only to be able to add more than 2 brackets, for example, sum (2) (3) (4) (5) ... N

Reported as a duplicate by Grundy , pavel , Community Spirit 28 Oct '16 at 15:34 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

  • wait, i have deja vu? - Igor
  • if somewhere there is such a question, then throw off the pzhl answer) - Maksim
  • @Igor, occasionally float :-) - Grundy
  • one
    @AlexKrass, why? for example, my answer completely solves his problem - Grundy
  • one
    @Maksim, what is the measure of elegance? :-) In general, the approach is one: to return a new function, perhaps yourself, with a rewritten toString or valueOf and a closed value - Grundy

2 answers 2

Something reminds katu from CodeWars, but simpler.

 function sum(n){ sum.result += n; return sum; } sum.result = 0; sum.valueOf = sum.toString = _ => sum.result; console.info(sum(1)(2)(3)); 

  • Comments are not intended for extended discussion; conversation moved to chat . - Nicolas Chabanovsky
  • @NicolasChabanovsky, I protest - I was not offered to create a chat. The rest, I think, too. Emphasizes the need to add this link, regardless of the desire of the system to hint. - user207618
  • Strange, usually after 20 comments the system offers to go to chat. - Nicolas Chabanovsky
  • @NicolasChabanovsky, I noticed - only if the two correspond. If a third party intervenes, there will be no link. - user207618

The approach to creating functions that can be called in a row an unknown number of times in advance is quite standard:

  1. For the result to be called as a function, you need to return a function.
  2. 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.
  3. 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)); 

  • It is strange to see spread and normal functions. And the storage method is good, although slightly verbose, since there is no “protect the result” in the condition. - user207618
  • @Other, but I like the usual functions :-) in the arrows there is no such thing - this , although it is not used here :-) - Grundy
  • So in this and salt. Arrows easier, faster and less write. After all, there is no this , super or arguments . - user207618
  • @Other, by the way, looked bad :-) I have them used in reduce, and the rest is copy-paste from the previous solution :) - Grundy
  • I did not say that all are not arrows, but that they are, although, it seems, they are not needed. - user207618