[ActionScript 3.0] ループ内のクロージャ

var timer:Timer = new Timer(100, 1);

for (var i:int = 0; i < 5; i++) { timer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void { trace(i); } ); } timer.start(); /* result 5 5 5 5 5 */ [/as3] この例の場合、一見すると問題がないかのように見える。 しかし、クロージャに受け渡される外側の関数(メソッド)のデータのまとまり(ローカル変数の状態)は、あくまで外側の関数の内部処理が最後まで実行された時点のもののため、結果のようになってしまう。 これを防ぐには、ループ内部の処理を別の関数・クロージャで行い、必要なローカル変数を引数に渡せばいい。 [as3] var timer:Timer = new Timer(100, 1); for (var i:int = 0; i < 5; i++) { setListner(i); } timer.start(); function setListner(num:int):void { timer.addEventListener(TimerEvent.TIMER, function (e:TimerEvent):void { trace(num); } ); } /* result 0 1 2 3 4 */ [/as3] クロージャ(ラムダ関数)はどの言語でも、けっこう動作がトリッキーなので注意するようにしよう。 # ActionScript 3.0の場合、他に参照が切れないことによるメモリリークの問題もある。

ActionScript 3.0

Posted by takasho