ActionScript 2.0で「this必須宗」の復活 [Edit]

ActionScript 2.0のクラス定義では、クラスのインスタンスを参照する場合に、原則としてthis参照は不要です。thisは、自動的に補われるからです。ところが、this参照をつけないと、スクリプトが正しく動作しない場合があります。「this必須宗」が、一部で復活の兆しです。

つぎのようなActionScript 2.0クラスを定義してみましょう。MovieClipシンボルに設定しますので、MovieClipクラスを継承します[*1]。原則に従えば、this参照は一切不要のはずです。

スクリプト001■ドラッグ&ドロップを行うActionScript 2.0クラス定義
// ActionScript 2.0クラス定義ファイル: MyMovieClip.as
class MyMovieClip extends MovieClip { // MovieClipクラスを継承
  function onPress() {
    startDrag(); // thisなしではコンパイルエラー
    // [1]対応策: thisを参照する
    // this.startDrag();
  }
  function onRelease() {
    stopDrag();
    trace(eval(_droptarget));
    // [2]対応策: thisを参照する
    // trace(eval(this._droptarget));
    // [3]対応策: (なぜか)ステートメントを分ける
    // var droptarget_str:String = _droptarget;
    // trace(eval(droptarget_str));
  }
  function stopDrag() {
    trace("stopDrag() method is called");
    super.stopDrag();
  }
}

[1]コンパイルすると、「パラメータの数が間違っています。startDragは1から6のパラメータが必要です」というエラーが表示されます。結果として、MoiveClip.startDrag()メソッドでなく、グローバル関数のstartDrag()が呼出されているようです[*2]。

しかし、stopDrag()は、問題ありません。一見、グローバル関数のstopDrag()は引数を取らないので、エラーが発生しないようにも解釈できます。しかし、クラスに以下のstopDrag()メソッドを追加すると、正しく呼出されます。つまり、stopDrag()にはthis参照が補われて、インスタンスのメソッドとして扱われていることがわかります。

スクリプト2■startDrag()メソッドの追加
  function stopDrag() {
    trace("stopDrag() method is called"); // 出力される
    super.stopDrag();
  }

[2]もうひとつ、MovieClip._droptargetプロパティの挙動も不審です。eval()関数は、ストリングで記述されたパスを、参照に変換します。ですから、ドロップ先にMovieClipインスタンスが存在すれば、[出力]パネルにはそのターゲットパスが表示されるはずです。

ところが、実際にはスラッシュシンタックスのパスが、文字列のまま[出力]されます。これは、きわめて奇妙な結果です。しかし、これもthis参照をつけると、正しくターゲットパスを表示します。

[3]MovieClip._droptargetプロパティの値を一旦ローカル変数に取得してから、その変数をeval()関数に渡しても、問題は解消します。

_____
[*1]クラスは、[シンボルプロパティ]に[AS 2.0クラス]として設定します。

[*2]MovieClipクラスを継承せずに、グローバル関数と同名のメソッドを呼出すと問題が生じることについては、「ActionScript 2.0クラスからグローバル関数と同名のfunctionが呼べない」をご参照ください。

その他の記事