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日