I was testing the callback mechanism in node.js to see the context in which a callback is fired. While running the following code I’ve noticed a strange behavior and I wonder if you could explain:
var outID =2;
var closure = function (){
var that = {};
that.id = 1;
outID = 3; //if line is commented out outID will always be 2.
that.inside = function(cb){
console.log("level 0");
console.log("thatID:" +that.id);
console.log("outID:" +outID);
setTimeout(function(){
console.log("level 1");
console.log("thatID:" +that.id);
console.log("outID:" +outID);
setTimeout(function(){
setTimeout(cb,0,that.id);
},0);
}, 0);
};
return that;
};
var level3 = function(id){
console.log("level 100S");
console.log("id " + id);
console.log(outID); // --- Interesting value is 3.
};
var cl = new closure();
cl.inside(level3);
Output is:
node: no process found
level 0
thatID:1
outID:3
level 1
thatID:1
outID:3
level 100S
id 1
3
[Finished in 0.1s]
Why is the last value 3 and not 2 ?
outIDis declared (i.e., using thevarkeyword) at the top level scope, and never redeclared in any other (function) scope. This means that when it’s assigned to, anywhere, it’s writing to the same variable, and when it’s referenced, anywhere, it’s reading from the same variable.To keep the
outID=3line in the inner function from changing the value printed last, you’d change it tovar outID=3.Edit:
The code posted has the following scopes:
As that hopefully makes clearer, a functions scope inherits from the scope in which it is defined, not the scope in which it is called. Of course, you might be conflating scope with the value of
this, which is another story…