なんか書いてる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](); }