Heres a sample bit of code, similar to that that gave me grief:
for(var i=0;i<3;i++){
var Proof = true
if (i == 0){
Proof = false
//var CallBack = function(){alert(Proof);}; // true????
var CallBack = function(){alert(i);};
}
}
// Whatever happened to local scope? shouldn t CallBack be undefined now?
CallBack()// alert(3), should be 0?
CallBack isn t undefined, it alerts true or 3, could someone please explain to me what is going on that is making it act like this? is there some local keyword I am missing, or does JS not have scope? I am using no framework, and would appreciate some help on how to sort this out, and do this kind of thing properly...
JavaScript doesn t have block scope at all (yet, see below). All variables are declared throughout the function in which they appear (or throughout the global scope, if they re at global scope).
Assuming the code you ve quoted is the only code in its scope, it s exactly the same as this:
var i;
var Proof;
var Callback;
for(i=0;i<3;i++){
Proof = true
if (i == 0){
Proof = false
//CallBack = function(){alert(Proof);}; // true????
CallBack = function(){alert(i);};
}
}
// Whatever happened to local scope? shouldn t CallBack be undefined now?
CallBack()// alert(3), should be 0?
http://blog.niftysnippets.org/2008/03/poor-misunderstood-var.html
http://blog.niftysnippets.org/2008/03/poor-misunderstood-var.html
CallBack()// alert(3), should be 0?
No, 3 is correct, because that s the value of i as of when CallBack is called . CallBack is a closure over the context in which it was created. It has an enduring reference to the context (including the i variable), not a copy of what existed when it was created.
If you wanted to get 0 instead, you d have to have CallBack close over something other than i, something that won t change. The typical way to do that is to use a builder function you pass a value into:
function buildCallBack(index) {
return function() { alert(index); };
}
Then:
CallBack = buildCallBack(i);
The value of i is passed into buildCallBack as the argument index. buildCallBack creates a function closing over the context of that call to buildCallBack and using that index argument. Since that argument s value is never changed, the callback alerts 0 (in this case) rather than 3.
http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html
http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html
http://wiki.ecmascript.org/doku.php?id=harmony%3ablock_scoped_bindings
http://wiki.ecmascript.org/doku.php?id=harmony%3ablock_scoped_bindings
http://stackoverflow.com/questions/20990661/how-does-javascripts-scope-work-getting-unexpected-behavior