Reputation: 1357
Why does this code work? - http://jsfiddle.net/Mq9Ap/1/
$(function() {
function outer() {
var counter = 0;
function inner() {
alert(counter);
counter++;
}
return inner;
}
var x = outer(); // As we're calling outer here, x is a reference to inner
x(); // alerts 0
x(); // alerts 1
});
But it only runs once if i change return inner
to return inner()
Edit:
I've confused the intent of my question by mentioning parenthesis. I'm still confused how the inner function is called at all as x() only points to the outer function.
Does the compiler know it should invoke a function if the return value is a pointer to a function?
Upvotes: 0
Views: 60
Reputation: 1357
I think I've cracked it; my confusion was not so much return inner;
but it was:
var x = outer();
I now understand that x holds the return value of outer because of the () invocation which is a function reference to b
, so if we now add another () around this returned value, it then invokes that referenced inner function, similar to outer()();
function outer() {
var counter = 0;
function inner() {
console.log(counter);
counter++;
}
return inner;
}
outer()();
outer()();
outer()();
//output
0
0
0
var x = outer();
x();
x();
x();
//output
0
1
2
The last section var x
works because the outer has been invoked with outer()
. When the inner is then called with x();
each time, the counter is already on the stack so the inner function sees it as a static var...i presume.
Confusing stuff this javascript :(
Edit:
Another eureka moment - I realised that outer()();
doesn't work because each time the first outer()
is called, it creates a new function context and var counter
is initialised each time on the stack and when the second invocation is called, the counter will always be set to zero.
The x = outer();
keeps the counter value from previous function calls, because the function context is saved in x
and var counter
is only initialised once so it's never reset.
Upvotes: 0
Reputation: 92865
It is the fact of what you return.
return inner();
actually call the inner function and get the result. That result will be returned. Since inner
function does not return anything explicitly, by default it returns undefined
. Now x
is undefined. You cannot make call on undefined x
.
return inner;
actually returns reference to inner function. So now x
is reference to a function. You can execute x()
which will actually invoke inner
closure function.
Upvotes: 0
Reputation: 95558
When you do return inner();
, you are actually invoking inner
and returning the return value , which in this case is undefined
since nothing is actually returned. This will then result in an error because undefined
is not a function (when you try to call it by doing x()
).
When you do return inner;
, you are actually returning a reference to the inner function.
Upvotes: 0
Reputation: 324750
return inner
returns the inner function. This can then be called.
return inner()
immediately runs the inner function (alerting 0
), then returns its return value (undefined). You then get an error that undefined
is not a function (when x()
tries to call it).
Upvotes: 2