Reputation:
Can somebody explain to me how the toString trick works in the following example. The function adds all the arguments being passed for each call so add(1)(2)(3);
equals 6.
function add(a) {
var sum = a;
return function self(a) {
sum += a;
self.toString = function () {
return sum;
}
return self;
}
}
console.log(add(1)(2)(3));
Upvotes: 4
Views: 121
Reputation: 190915
It is returning itself which is a function. The self
function also closes around sum
. Then console.log
is using the overridden toString
.
Basically, this is happening
var a = add(1); //a is a self
var b = a(2); //b is the same self (b === a)
var c = b(3); //c is a same self (c === a && c === b)
console.log(c); // calls c.toString()
It isn't the add
function getting called multiple times, it's the self
function.
Upvotes: 1
Reputation: 700252
The function add
declares a variable sum
and returns a function that has two purposes:
You can call the function with a value, which will add the value to sum
and return the same function.
You can get the string value of the function, which will return the value of sum
.
So, the value of add(1)
is a function, where sum
is 1.
The value of add(1)(2)
is a function, where sum
is 3.
The value of add(1)(2)(3)
is a function, where sum
is 6.
The console.log
call will get the string value of the function, which is sum
.
You can also write basically the same code like this, which might be somewhat easier to follow:
function add(a) {
var sum = a;
function self(a) {
sum += a;
return self;
}
self.toString = function () {
return sum;
};
return self;
}
console.log(add(1)(2)(3));
(The difference is that toString
is bound by the function add
, not each time that you call the returned function. The edge case is that console.log(add(1))
shows 1
instead of self(a)
.)
Upvotes: 1
Reputation: 324620
Since the function is a chain function, you need to return a function to be chained which then returns itself.
However, you also need a meaningful way to get its result.
In jQuery, for example, you might see .get()
used to extract results from a chained operation. This is much the same, using .toString()
to mean "if you're putting me somewhere a string is expected, return the result".
Upvotes: 3