I am confused in this topic which is important to me in terms of asynchronous function calls and closures. I must have missed the most important part of javascript function invocation and wasn't able to find an answer to my question up to now, hence I hope for your help!
My question assumes:
- An outer function
fDynamic
is called with some argumenti
( = 0 ) fDynamic
queues an inner functionfInnerQueued
, to be invoked at some point in time in the future.- In the mean time the outer function
fDynamic
is invoked again with different argumenti
( = 1 )
Is this new argument value now visible to the first inner function fInnerQueued
which will see the changes as soon as it is finally invoked? ... it seems not?
It seems as if the function arguments are not free variables and are bound tightly to the function invocation scope even trough asynchronous calls.
Here's a fiddle and here the essence:
var j = 0;
var fDynamic = function( i ) {
j = i; // j seems to be a free variable, while i is not?
if( i == 0 ) {
// Delay execution in order to let i change to 1
var fInnerQueued = function() {
console.log(i + ' ('+ j + ')'); //should be "1 (1)" but is "0 (1)"
}
setTimeout( fInnerQueued, 100);
} else {
console.log(i); // is "1 (1)", right!
}
}; // Expected output "1 (1)", "1 (1)" but it is "1 (1)", "0 (1)"...
fDynamic(0);
fDynamic(1);
I tested it also on node.js and got the same, somewhat unexpected, output.
I crawled through different posts and didn't manage to find an answer:
- How do JavaScript closures work? & How does the outer function "store" the arguments for the inner function?: not explained in the asynchronous context
- accessing outer caller function arguments: also not in the asynchronous context
- Understanding closures: Constructing a meta-function that queues functions together: Went into the right direction but still the arguments of the outer function do not change in this question.
I know I can omit the hassle by creating shielded closures or using bind. But I really want to understand why function arguments are not considered free variables to inner functions and they are even retained through asynchronous calls.