なんか書いてるjsのコードでの問題が切り離せたので備忘録に。
var array = [];
for(var i=0; i < 3; i++){
console.log("i=", i);
array.push(function(){
console.log("in function ", i);
});
array[i]()
}
console.log(array.length);
for(var j=0; j < array.length; j++){
console.log("run function no.", j);
array[j]();
}
こういうコードで、最後の配列に入った関数を実行するときに、
run function no. 0
in function 0
run function no. 1
in function 1
run function no. 2
in function 2
となることを期待していたというのが本質のバグ作ってた。このコードの最後は実際は、
run function no. 0
in function 3
run function no. 1
in function 3
run function no. 2
in function 3
と実行される。「なんで"i<3"なのにi=3になってるんだよ!」という類のことで悩んでいたのだが、カウンタが生きているならば、forが終ったあとはその制約の一個次になるんだったなあと高校のBASICの授業を思いだす。
DIM I
FOR I = 0 TO 3
PRINT I
NEXT
PRINT I
みたいに書くと(正確な文法忘れた)
0
1
2
3
4
となるはず
追記
"JavaScript: The Good Parts"のクロージャの章に全く同じの載ってました。結局こう直します。
var array = [];
for(var i=0; i < 3; i++){
array.push(function(j){
return function(){
console.log("in function (revised): ", j);
};
}(i));
}
for(var j=0; j < array.length; j++){
console.log("run function no.", j);
array[j]();
}