[AS]クロージャのイイ感じの使用用途
クロージャとは、functionの中にfunctionを書くような書き方。(だと思う)
フレームに書いたらこんな感じ。
//フレームアクション
function test(){
var func:Function = new Function();
func = function(){
trace("func内this : " + this);//出力:func内this : [object global]
}
trace("test内this : " + this);//出力:test内this : [object MainTimeline]
func();
}
test();
これ使うと関数内のthisが何を示すか混乱するのよ。(私にとっては、ね)。
なので、あまり使わないようにしてたけど、便利そうな使い方を教わったのでご紹介。
たとえば、フェードイン処理とフェードアウト処理について。
以下のように書くことですっきりまとまる。
package {
public class Main extends Sprite {
//関数をインスタンス化しておく
private var fader:Function = new Function();
public function fadeIn( speed:Number ) : void {
//※addEventListenerされてない状態をremoveしてもエラーにはならない
removeEventListener( Event.ENTER_FRAME, fader )
//リスナー関数をaddEventListenerと同じ位置にかく
//fader関数の中身を設定
fader = function( e:Event ) : void {
alpha += speed;
if( alpha >= 1 ) {
removeEventListener( Event.ENTER_FRAME, fader )
}
}
addEventListener( Event.ENTER_FRAME, fader )
}
public function fadeOut( speed:Number ) : void {
//※addEventListenerされてない状態をremoveしてもエラーにはならない
removeEventListener( Event.ENTER_FRAME, fader )
//fader関数の中身を設定
fader = function( e:Event ) : void {
alpha -= speed;
if( alpha <= 0 ) {
removeEventListener( Event.ENTER_FRAME, fader )
}
}
addEventListener( Event.ENTER_FRAME, fader )
}
}
}
ポイントのひとつは、フェードインもアウトも同じfaderという関数を使っているところ。
インとアウトが同時実行されることはない。(remove処理が確実に行われる)
同時に実行させる必要があれば、新しいFunctionインスタンスを作ればよい。
あと、Functionインスタンスがnullでなければ、addEventListenerしてない状態で、removeEventListenerしてもエラーにはならない。
この書き方なら、フェード処理をもっと細かく設定したい場合も以下のようにすっきりかける。
//フェードイン関数のみ抽出
public function fadeIn( speed:Number ) : void
{
removeEventListener( Event.ENTER_FRAME, fader )
fader = function( e:Event ) : void
{
alpha += speed;
//追加:アルファが0.5以上になったら、スピードを半分にする
if( alpha >= 0.5) {
removeEventListener( Event.ENTER_FRAME, fader )
fader = function( e:Event ) : void
{
alpha += speed/2
if( alpha >= 1) {
removeEventListener( Event.ENTER_FRAME, fader )
}
}
addEventListener( Event.ENTER_FRAME, fader )
}
}
addEventListener( Event.ENTER_FRAME, fader )
}
Tweet