Oct 16, 2009

fixed a closure bug

Closure refer the ability that a function can access and manipulate external variable from with a function. Sometimes, this is not good because the if a function depends on the external state. When the external state changes, the function may produce unexpected result.

//this is because the function inside setTimeout refers to the i only when it is 
//executed, by then i==4, the problem is that i is external variable

for (var i = 0; i < 4; i++) {
            setTimeout(function() {
                alert(i); //it is always 4
            }, i * 1000);
    }

//the solution is make the i as local variable, so parameter is a solution, and
//self-execution

var count = 0;
for (var i = 0; i < 4; i++) {
    (function(j) {
        setTimeout(function() {
            alert(j); //it will show 0, 1, 2, 3
        }, j * 1000);
    }) (i);
}

So sometimes it is good to remove the external dependencies. The follow code is anther example.

var ninja = {
    yell: function(n) {
        return n > 0 ? arguments.callee(n - 1) + "a" : "hiy";
    }
}

/*      
this is also ok
var ninja = { yell: function x(n) {
return n > 0 ? x(n - 1) + "a" : "hiy";
}
};
*/

/*this is has bug, because ninja.yell is inside of function which depends external state
var ninja = { yell: function(n) {
return n > 0 ? ninja.yell(n - 1) + "a" : "hiy";
}
};
*/

var sumurai = { yell: ninja.yell };
ninja = null;
ok(sumurai.yell(4) == "hiyaaaa", "argumnets.collee is the function itself");