AS2でおなじみの手法は
AS3で「望ましくないイベントリスナー登録の方法」になったらしい。
バインドメソッド、メソッドクロージャの理解はやはり重要。
イベントリスナー — Flex 2.01 望ましくないイベントリスナー登録の方法
第 3 のテクニックとして、汎用オブジェクトを作成し、そのオブジェクトのプロパティによって動的にリスナー関数を割り当てる方法がありますが、これを使用することはお勧めできません。この方法を説明するのは、ActionScript 2.0 で一般的に使用されていたという理由からです。ActionScript 3.0 では使用しないでください。このテクニックでは this キーワードの参照先がリスナーオブジェクトではなくグローバルオブジェクトになるため、望ましくありません。
[object global] というのが、参照先を見失ってしまっている状態?
/* ActionScript3 */
import flash.events.MouseEvent;
var testData1:String = "TEST1";
var myListenerObj:Object = new Object();
myListenerObj.testData2 = "TEST2";
myListenerObj.onMouseUpFunc1 = function (e:MouseEvent):void
{
trace("event.type: " + e.type); //結果: event.type: mouseDown
trace("this: " + this); //結果: this: [object global]
trace("this.testData1: " + this.testData1); //結果: this.testData1: undefined
trace("this.testData2: " + this.testData2); //結果: this.testData2: undefined
};
function onMouseUpFunc2 (e:MouseEvent):void {
trace ("event.type: " + e.type); //結果: event.type: mouseUp
trace ("this: " + this); //結果: this: [object MainTimeline]
trace ("this.testData1: " + this.testData1); //結果: this.testData1: TEST1
}
stage.addEventListener (MouseEvent.MOUSE_DOWN, myListenerObj.onMouseUpFunc1);
stage.addEventListener (MouseEvent.MOUSE_UP, this.onMouseUpFunc2);
this の参照先は myListenerObj であるかのように見え、
トレース出力も [object Object](なっていない...)、実際の参照先はグローバルオブジェクトです。動的なプロパティ名を addEventListener() のパラメータとして指定した場合、Flash Player はバインドメソッドを作成できません。なぜなら、その場合に listener パラメータとして渡されるのはリスナー関数の単なるメモリアドレスであり、Flash Player がそのメモリアドレスと myListenerObj インスタンスを結び付ける手段がないからです。
になっていますが
/* ActionScript3 */ class ThisTest { private var num:Number = 3; function foo():void // 定義されたバインドメソッド { trace("foo's this: " + this); trace("num: " + num); } function bar():Function { return foo; // 返されたバインドメソッド } } var myTest:ThisTest = new ThisTest(); var myFunc:Function = myTest.bar(); trace(this); // 出力 : [object global] myFunc(); /* 出力 : foo の this: [object ThisTest] 出力 : num: 3 */
なんとなく [object global] の場所を理解した。
- 関連エントリー
Function.apply
メソッドクロージャ