How to achieve an arbitrary chain when calling a function in javascript?

I wrote code to achieve

sum(1)(2) //3 

The code is as follows:

 function sum(a) { return function(b) { return a+b } } 

But I did not formulate the second question, which is how to achieve any arbitrary number of function chain calls, for example:

 sum(1)(2) == 3 sum(5)(-1)(2) == 6 sum(6)(-1)(-2)(-3) == 0 sum(0)(1)(2)(3)(4)(5) == 15 
+5
source share
4 answers

Usually you do something like this:

 var add = function(a,b){ return a+b; }; var sum = function(){ return [].reduce.call(arguments, add); } 

And then you can write:

 sum(1,2,3,4); // 10 

But you can hack the functionality you use:

 var sum = function(x){ var f = function(y){ return sum(x+y); }; f.valueOf = function(){ return x; }; return f; }; sum(1)(2)(3)(4); // 10 

Just don't do it in production code, please!

+9
source

You cannot do this - how does the sum function know if you want to return an answer or another function?

You could do something in this direction:

 sum(0)(1)(2)(3).result() 

Implemented as follows:

 var sum = (function(){ var total = 0; var f = function(n){ total += n; return f; }; f.result = function(){ return total; }; return f; }()); 
+1
source

As already stated in the user code: This is not possible.

Instead, you can use the current function parameter. If there is no parameter, you can return the result:

 sum(1)(2)() == 3 

Here is the implementation:

 var sum = (function() { var total = 0; return function add(a) { if(a === undefined) { return total; } total += a; return add; }; }()); 
+1
source

There are several different ways to pass an "arbitrary" number of arguments to a function. Perhaps the most useful for your case is the arguments object. Within each function, there is an object similar to an array that contains all the arguments passed to the function.

 function shout(msg) { for (var i = 0; i < arguments.length; i++) console.log(arguments[i]); } shout("This", "is", "JavaScript!"); // Logs all three strings, one line at a time 

Despite the fact that it seems that the function takes only one argument, you can connect as many as you want, and the function will cycle through all of them. Thus, converting this to your code:

 function sum(a) { var total = 0; for (var i = 0; i < arguments.length; i++) total = total + arguments[i]; return total; } sum(1, 2); // Returns 3 

Two things to note:

  • Since you are accessing the arguments object, you really don't need β€œany” argument list in the function definition (that is, you don't need a in sum(a) ), but it is usually considered a good idea to give some idea of ​​what the function expects. .
  • The arguments object is similar to an array, but is NOT a true array; do not try to use array functions on it, such as push or pop, unless you want to get confused about things.

Regarding the specific syntax sum(1)(2) , however - if it is very specific what you need - I'm at a dead end. Theoretically, to have such a chain, you would need your function to return an object, which is both a function and a number ... that violates the basic rules of JavaScript. I do not think that this is possible without any extremely smart (and probably extremely dangerous) editing of built-in objects, which, as a rule, is frowned upon if there is no good reason for this.

0
source

Source: https://habr.com/ru/post/1205876/


All Articles