サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

ActionScript 2.0クラスからグローバル関数と同名のfunctionが呼べない

ID: FN0406002 Product: Flash

Platform: All
Version: MX 2004

1. 現象
ActionScript 2.0クラスに、グローバル関数と同じ名前のfunctionを定義すると、呼出しのできないことがあります。

たとえば、以下のクラス定義ファイルでは、コンストラクタ関数内から関数play()を呼出しています(スクリプト001)。しかし、クラスインスタンスを生成しても、インスタンスメソッドplay()は実行されません。さらに、コメントアウトされたステートメントを有効にして、ローカルfunctionとしてplay()を定義しても、同様に呼出されません。

スクリプト001■コンストラクタ関数からメソッドが呼出せないActionScript 2.0クラス定義ファイル

// ActionScript 2.0クラス定義ファイル: UseKeywordAsMethod.as
class UseKeywordAsMethod {
  function UseKeywordAsMethod() {
    // var play = function () {trace("The inner function is called");};
    play();
  }
  function play() {
    trace("The play method is called!");
  }
}

2. 原因
スクリプト001のActionScript 2.0クラス定義ファイルを作成したうえで、Flashムービー(SWF)に以下のフレームアクションを定義してみましょう(スクリプト002)。

[ムービープレビュー]を実行すると、[出力]ウィンドウには何も表示されず、メソッド(あるいはローカルfunction)play()は呼出されていないことがわかります。しかし、スクリプトを記述したタイムラインが、MovieClip.stop()メソッドで停止しているにもかかわらず、つぎのフレームに移動してしまいます。

スクリプト002■テスト用フレームアクション

// Flashムービー(SWF)
// フレームアクション
this.stop();  // タイムラインを停止
var obj:UseKeywordAsMethod = new UseKeywordAsMethod();

タイムラインのフレームが移動するのは、play()がクラスに定義されたfunctionでなく、Flash 2互換のグローバル関数として認識されていることを意味します。グローバル関数は、functionのスコープよりも優先して呼出されるようです。そのため、ローカル変数に名前のない関数として設定したfunctionも、実行されません。

3. 対処法
インスタンスメソッドを呼出すには、this参照を加える方法があります(スクリプト003)。this参照により、グローバル関数でなくメソッドを使用することが明示され、クラスに定義されたインスタンスメソッドplay()が呼出されます。

// コンストラクタ関数を呼出してインスタンスを生成した場合の[出力]
// The play method is called!

スクリプト003■this参照によりメソッドを呼出すActionScript 2.0クラス定義ファイル

// ActionScript 2.0クラス定義ファイル: UseKeywordAsMethod.as
class UseKeywordAsMethod {
  function UseKeywordAsMethod() {
    this.play();  // thisを参照
  }
  function play() {
    trace("The play method is called!");
  }
}

しかし、ローカル変数に定義したfunctionは、参照を加えることができません。この場合には、変数(function)名を、グローバル関数と競合しない別の識別子で宣言するしかないでしょう。

4. MovieClipクラスを継承した場合の問題
クラスがMovieClipを継承すると、this参照なしでもインスタンスメソッドが呼出されるようになります(スクリプト004)。

スクリプト004■コンストラクタ関数からメソッドが呼出せないActionScript 2.0クラス定義ファイル
 

// ActionScript 2.0クラス定義ファイル: UseKeywordAsMethod.as
class UseKeywordAsMethod extends MovieClip {
  function UseKeywordAsMethod() {
    // ローカル変数に定義した名前のない関数は呼出せない
    // var play = function () {trace("The inner function is called");};
    play();
  }
  function play() {
    trace("The play method is called!");
  }
}

しかし、ローカル変数に定義した名前のない関数はやはり呼出されず、同名のインスタンスメソッドが実行されてしまいます。これは、ActionScript 2.0のバグだと考えられます。

_____

作成者: 野中文雄
作成日: 2004年6月11日


Copyright © 2001-2006 Fumio Nonaka.  All rights reserved.