node.js parameter concealed

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 ?

outID is declared (i.e., using the var keyword) 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=3 line in the inner function from changing the value printed last, you'd change it to var outID=3.

Edit:

The code posted has the following scopes:

global 
    closure
         that.inside
             $anonymous1 (outer setTimeout argument)
                  $anonymous2 (inner setTimeout callback)
    level3

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...