kagamihogeの日記

kagamihogeの日記です。

ActionScript の Function 型の勉強 - 2

ActionScript の Function 型の勉強 - kagamihogeのblog

ActionScript はさすが ECMAScript の系譜を引いてるからなのかなんなのか、関数の扱い方が素晴らしくダイナミック。元々 Java 屋さんな俺からするとちょっとドン引きレベルにパワフルです。

var mo:Object = new Object();
mo["hoge"] = function():void {trace("hoge");}
mo["hoge"](); // hoge と表示

こんな感じに、インスタンスに対して動的に関数が追加できる。関数名(プロパティと言ったほうがいいのかな)を文字列で指定できるので、結構やりたい放題です。

追加する関数は function の体裁をとっていればいいので、こういう書き方もモチロン可能。また、関数の呼び出しは文字列でもいいし、"." で指定してもいい。

private function hogeMethod(n:int):void {
    trace("hogeMethod="+n);
}

var mo:Object = new Object();
mo["hogeMethod"] = hogeMethod;
mo.hogeMethod(10);    // hogeMethod=10 と表示

mo["hogeMethod"](20); // hogeMethod=20 と表示

インスタンスにその名前のプロパティがあるかどうかは Object#hasOwnProperty(name:String) で調べられる。削除は delete 演算子で行う。

var mo:Object = new Object();
mo["hoge"] = function():void {trace("hoge");}

trace(mo.hasOwnProperty("hoge")); // true と表示
delete mo["hoge"];
trace(mo.hasOwnProperty("hoge")); // false と表示

自前で定義したクラスに対してはこうした動的なプロパティの追加は出来ない……のだけど、クラス定義に dynamic を付与することで可能になる。

public dynamic class Hoge
{
    public function m():void {
        trace("function m()");
    }
}

var s:Hoge = new Hoge();
s.m2 = function():void {trace("hoge");}
s.m2(); // hoge と表示
s["m2"] = function():void {trace("hoge 2");}
s["m2"](); // hoge2 と表示

s["m2"]() はともかく、s.m2() でも呼べてしまう。元のクラスには定義されてすらいないのになぁ……w そういうもんだとは思っても、なんか、すごい違和感が……

ともあれもうちょっと実験。

var s:Hoge = new Hoge();
delete s["m"];
trace(s.hasOwnProperty("m")); // true と表示される。

静的に定義してるプロパティは delete できない。まぁ当たり前といえば当たり前。

次に上書きを試みてる。

var s:Hoge = new Hoge();
s["m"] = function():void {trace("hoge 3");}

さすがにこれは「ReferenceError: Error #1037: Hoge のメソッド m に代入できません。」とエラーになる。

いやはや。AS はフリーダムだなぁ……