ActionScript2.0メモ:イベント時のスコープ(変数の参照範囲)

クラス内でイベントを記述した場合、
呼び出すメソッド内から、クラス変数が参照できない問題があったのでメモしておきます。

class Test{
	var str:String = "test";
	function Test(MC:MovieClip){
		trace("output" + val);
		//MC(MovieClip)をクリック時、Methodメソッドを実行する
		MC.onPress = Method;
	}
	
	function Method():Void{
		trace(str);
	}
}

上記のように、MovieClipのonPressイベントでMethodメソッドを呼び出して変数strを出力させようとしています。
「test」が出力されることを期待して記述しましたが、実際にこれでは「undefined」が出力されてしまいます。

どうやらこれはスコープ(変数の参照範囲)が、イベントで呼び出したメソッド内では変わってしまうことが原因になるようです。

onPress等のイベントを記述する場合、「MC.onPress」のように記述するかと思いますが、
このようにした場合、どうやら「MC」をスコープに指定されてしまうようです。

従って、イベントで呼び出したメソッド内のstr変数はクラス変数の「str」ではなく、「MC.str」を読み出そうとして、そのために「undefined」になってしまうようです。


これを解決するためには、mx.utils.Delegateクラスを使う必要があります。
記述方法は下記のようになります。

import mx.utils.Delegate;

class Test{
	var val:String = "test";
	function Test(MC:MovieClip){
		trace("output" + val);
		//MC(MovieClip)をクリック時、Method関数を実行する
		MC.onPress = Delegate.create(this,Method);
	}
	
	function Method():Void{
		trace(val);
	}
}

前述したコードとの違いは、クラス定義の前に「mx.utils.Delegate」をインポートしている点と、
Delegate.createメソッドを介して、Methodメソッドを処理させている点だけです。

これにより、this(クラス自身)をスコープに指定して、メソッドを実行させることができます。



また、setIntervalでも同じ現象が起きますが、

setInterval(Delegate.create(this,Method) , 1000);

上記のように記述すれば、this(クラス自身)をスコープに指定して、実行させることができます。


私がActionScript2.0でクラスを扱うようになって1年ほどになりますが、この問題には長い間頭を悩まされました…
だって私が持っている本にはスコープとかDelegateなんて載ってなくて…;
こういうときはWebや公式のテキストが役に立ちますね。

ところで私が持ってるのがFLASH8なので未だActionScript2.0のメモです…;
8で3.0使う方法ってないのでしょうか…?
CS3の次のバージョンでたら買うかなぁ…?
いつになるか分かりませんが…



コメント
コメントする








    
この記事のトラックバックURL
トラックバック