Reputation: 1172
I am new to the JavaScript world. Today while working with JavaScript I found the following snippet:
function sum (a) {
var sum = a;
function f (b) {
sum += b;
return f;
}
f.toString = function () {
return sum;
}
return f
}
//Calling the function
console.log(sum(4)(5));
Can you please help me understand when f.toString
is executed?
Upvotes: 4
Views: 449
Reputation: 1547
When sum(4)(5)
is executed, sum(4)
is executed first which returns the function f
.
This function have access to variable sum
(due to closure property of JavaScript functions[1]). This function does the summation and return the function f
again.
This time console.log
is trying to print the function f
and hence we are explicitly defining how function should be printed by defining f.toString
to print the sum.
Edit: If you are wondering why take so much pain to simply add two numbers then try the following:
add(2)(1)(45)(22)
This works because now f
is recursively called and sum
is updated, again due to closure property.
1: Inner functions have access to parent function's variable even after parent function has gone out of scope.
Upvotes: 3
Reputation: 413720
When you pass an object to console.log()
, it calls .toString()
in order to print out the value.
Thus,
sum(4)
returns a function. The subsequent call to that function
sum(4)(5)
also returns a function. Then that's passed to console.log()
, and the result in the console is
9
It should be noted that the console
API is a pretty shaky quasi-standard, and because it's designed as a debugging aid there are some behaviors that can be confusing. In this case however it seems to simply call .toString()
without any other "helpful" funny business. If, however, you were to just pass a simple empty object to console.log()
, like this
console.log({})
you get (at least from Firebug in Firefox) a helpful interface to navigate the object. That's great if you're debugging something, but if you're trying to see how the language works that behavior can be confusing.
As a final note, the trick in the posted code could be extended so that the function can divulge a numeric result too by adding a .valueOf()
method:
function sum (a) {
var sum = a;
function f (b) {
sum += b;
return f;
}
f.toString = function () {
return sum;
};
f.valueOf = function() {
return sum;
};
return f;
}
If you do that, then you get the right answer from
console.log(2 * sum(4)(5))
Upvotes: 4