2007/11/14
AS3:Function.applyの1個目の引数の有用性
AS2ではaddEventListenerのリスナー指定するときなどにDelegateを使ってましたが、
AS3では、ただ呼びたいメソッドを指定すればいいだけです。
しかしでは、Delegateの内部で行われていたFunction.applyの効用はどうなってしまったのか。
以下のコードをステージ上のタイムラインに書き、AS2とAS3で書き出してみました。
test();
var testObj = new Object();
test.apply(testObj);
function test(){
trace ("this is " + this);
}
//AS2の場合 //this is _level0 //this is [object Object]
//AS3の場合 //this is [object MainTimeline] //this is [object MainTimeline]
AS3では、一つ目の引数にターゲットとなるオブジェクトを指定しても、意味は無いようです。
このことをどう考えたらよいのかよく分からないのですが、とにかくそういうことのようです。
【追記】
コメントをいろいろいただきましたんでまとめなおします。
Live DocsのFunctionの項の説明によると、
関数は、ActionScript で呼び出すことのできるコードの基本単位です。ActionScript のユーザー定義関数とビルトイン関数は、どちらも Function クラスのインスタンスである Function オブジェクトで表されます。
クラスのメソッドは、Function オブジェクトとは少し異なります。メソッドは通常の関数オブジェクトとは異なり、関連のクラスオブジェクトと緊密にリンクされています。このため、メソッドまたはプロパティは、同一クラスのすべてのインスタンスで共有される定義を持ちます。メソッドをインスタンスから抽出して、"バインド" メソッドとして扱うことができます。元のインスタンスとのリンクは維持されます。バインドメソッドの場合、this キーワードで、メソッドの実装元オブジェクトを指します。関数の場合、this で、関数が呼び出されたときの関連オブジェクトを指します。
とのこと。
馬場の拙い理解では、おなじFunctionでも、クラスで定義するのは「メソッド」、a=function(){...]とか定義するのは「関数」と、微妙に別物なようです。
そして、メソッドの場合は、元のインスタンスへのリンクが維持され、関数の場合は維持されない。ということのようです。
var test2:Function = function() {
trace("test2: this is " + this);
};
var testObj = new Object();
test2();
test2.apply(testObj);
//AS2の場合 // test2: this is _level0 // test2: this is [object Object]
//AS3の場合 //test2: this is [object MainTimeline] //test2: this is [object Object]
functionを変数として定義してあげると、ちゃんとapplyされました。
これは、Function.callの場合にも当てはまります。
最初のコードでは、functionをタイムライン上で定義してますが、これも元インスタンスへのリンクが保持されているところをみると、クラスメソッドとして扱われていることなのか?
【追記2】
今日、人からまたちょっと話を聞いたのですが、結局、var a=function(){}という、匿名関数だけがapllyによるスコープの変更が効き、それ以外のメソッド定義の方法では、もうどうにも変更できない、ということでよい気がします。
コメント一覧