- 2005-10-07 (金)
- ActionScript
ActionScript2.0 でスクリプトを書いていて、いまいちターゲットパスの挙動が把握しきれなくてヤキモキしていたので、きっちり整理してみました。特にターゲットパス記述を省略した際の挙動に焦点をあてて。これで気分的にはすっきりしました :)
Table Of Contents
ターゲットパスの基本
※FLASH付属のヘルプドキュメントを参照 - Flashユーザーガイド > Flashドキュメントの操作 > 絶対ターゲットパスと相対ターゲットパス (\ja\Configuration\HelpPanel\Help\UsingFlash\00000125.html)
- _root : SWFが配置されているレベルを指す
- this : 現在のオブジェクトを指す
- _parent : 1階層上のオブジェクトを指す
ターゲットパス記述を省略した場合の参照先について - まとめ
結論から先に言うと、
- メインタイムライン上のスクリプト
= そのSWFの _root からの絶対パスを指す- インスタンス付随のスクリプト
= その instance の _root からの絶対パスを指す- リンケージクラス上のスクリプト
= リンケージが張られているインスタンスの _root からの絶対パスを指す
という挙動になります。これだけ見ると、なんだ全部挙動同じじゃんって感じですが、メインタイムライン上には「ステージ上の任意のインスタンスのコードも書ける」為、これら挙動の統一性が失われることになります。とりあえず、メインタイムラインとその他箇所ではパス省略時の暗黙解釈が異なる、という事を覚えておくべし。
ターゲットパス記述を省略した場合の参照先について - 解説
ターゲットパス記述を省略してオブジェクトや変数を扱う場合、内部的に参照するスコープは以下の通り、スクリプトを記述する場所によって異なるようです。
■メインタイムライン上のスクリプト
そのSWFの _root からの絶対パスを指す
以下の例がわかりやすいかと。
例1)とあるムービークリップインスタンス child をステージ上に配置した状態でメインタイムラインに以下のコードを記述:
var hoge = "xxx"; child.onPress = function(){ // 相対パスで hoge にアクセス trace(this._parent.hoge); // パス省略して hoge にアクセス可能 trace(hoge); }
結果、どちらも xxx を返します。2つめの trace の挙動が注目すべき点で、メインタイムライン上のスクリプトの場合、 記述場所のスコープ(この場合だと child)に関係なく、 常にSWFの _root からの絶対パスを指す事になります。
さらにもう1点。
ただし同一スコープ内に同名のローカル変数が宣言されている場合はそっちを参照
例2)とあるムービークリップインスタンス child をステージ上に配置した状態でメインタイムラインに以下のコードを記述:
var hoge = "global"; child.onPress = function(){ var hoge = "local"; trace(hoge); // 結果は local }
この場合は function() 内部で宣言されている方の hoge を優先的に参照するようです。まぁ、この辺の挙動は他の言語で見られる「グローバルスコープとローカル (lexical) スコープ」の挙動と同じなので理解はしやすいですね。
■インスタンスに付随させたスクリプト
ボタンなりムービークリップなりをマウスで選択した状態でアクションパネルにスクリプトを記述した場合の事を指しています。こうするとメインタイムラインとは別空間にスクリプトを記述/配置する事ができる... のですが世の中的にはこれが全体スクリプトのメンテナンス性を損なわせる主な原因となっている様子(Macromedia的にも非推奨のようです)。で、この場合の挙動ですが、
その instance の _root からの絶対パスを指す
になるようです。以下具体例。
例3)とあるムービークリップインスタンス child をステージ上に配置した状態でメインタイムラインおよび child に対してそれぞれ以下のコードを記述:
-- メインタイムライン ---- var hoge = "xxx"; -- child インスタンス ---- on(press){ trace("value of hoge is - " + hoge); }
結果、hoge の値は undefined となります。あれれ?さっきのメインタイムライン上のスクリプトと同様に hoge は _root.hoge を参照するはずじゃないの? と考えたくなりますが、そうはいかない模様。インスタンス付随のスクリプトの場合、ターゲットパス記述省略時は常にインスタンスの _root からの絶対パス になります。この例の場合は _root.child.hoge ですね。
■リンケージクラス上のスクリプト
ライブラリのムービークリップシンボルに対して、リンケージの設定を施す事により外部クラス(ASファイル)にスクリプトを記述する事ができます。この外部クラス上にてターゲットパスを省略すると、
リンケージが張られているインスタンスの _root からの絶対パスを指す
になるようです。先ほどのインスタンスに付随させた場合と同じです。以下具体例。
例4)とあるムービークリップインスタンス child をステージ上に配置した状態でメインタイムラインおよび child にリンケージを張った外部クラスファイルに対してそれぞれ以下のコードを記述:
-- メインタイムライン ---- var hoge = "xxx"; -- 外部クラス ---- class gaibu extends MovieClip { // constructor function gaibu(){ } // on press function onPress() { trace(hoge); } }
結果、これだとコンパイルエラーになります。インスタンス付随スクリプトの時と同様、この場合の hoge は _root.child.hoge を指し、さらに外部クラスの場合は、_root.child.hoge ... つまりは自分の hoge プロパティをクラスプロパティとして宣言していない為にエラーとなるようです。コンパイルエラーになるだけ、プログラマが気付く事ができるのでまだマシですね。
※以上の挙動を理解していれば、とりあえずターゲットパス関連の挙動で四苦八苦する事は無くなるかと思われます。理想としてはターゲットパス省略時の挙動を統一するか、省略記述は全部コンパイルエラーにするかしてもらえると無駄に苦労する事無いんですけどね... どうでしょうか Macromedia 殿。