IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

ActionScript では安全に Object 汚染をすることができる

Object 汚染とは

簡単に言うと Object.prototype を拡張したときに、すべての for in に影響を与えてしまって、いろんなことが困る。という問題である。
DontEnum という内部属性をスクリプトから与える手段がないために発生する。

Object.prototype.hoge = 'ほげ';

for (var p in {}) alert(p); // hoge と表示される

ActionScript では

setPropertyIsEnumerable という関数が Object.prototype に宣言されている。
これを使うことによって、安全にすべてのオブジェクトメソッドやプロバティを追加することができる。

例えば

以下のソースをコンパイルすると

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    public class Sample extends Sprite {
        public function Sample() {
            var textField:TextField = new TextField();
            textField.x = 10;
            textField.y = 10;
            textField.width = 400;
            textField.height = 400;
            addChild(textField);
            Object.prototype.hoge = 'ほげ';
            Object.prototype.fuga = 'ふが';
            Object.prototype.piyo = 'ぴよ';
            Object.prototype.setPropertyIsEnumerable('hoge', false);
            var o = {};
            for(var p in o) textField.text += o[p];
        }
    }
}

「ぴよふが」と表示される。「ほげ」が表示されていないのがわかる
以下のリンクはコンパイル済みの swf
http://sample.ecmascript.jp/Sample.swf

これが出来ると

すべてのオブジェクトに直接的に機能を付け加えることができる!!!
これはすっごい便利なことだと思う><

tamarin が世に出るときに、この機能はブラウザに実装されるのかな?どうだろう?楽しみ><

ActionScript の Object.prototype を拡張する実用的な例

このエントリの続きです。

d:id:amachang:20061220:1166630932
ActionScript では Object.prototype を書き換えていいので・・・、

実際に便利な関数を作ってみた

_def 関数

この関数は、 DontEnum な(for in で繰り返されない)プロバティを作る

Object.prototype._def = function(p, o) {
    this[p] = o;
    this.setPropertyIsEnumerable(p, false);
};
Object.prototype.setPropertyIsEnumerable('_def', false);
_merge 関数

この関数は、this に別のオブジェクトをマージする。上の _def 関数を使って作っています。

Object.prototype._def('_merge', function (o) {
    for(var p in o) this[p] = o[p];
    return this;
});

実際にこれを使うとどうなるか

使用前

たてながーん

var t = new TextField();
t.x = 10;
t.y = 10;
t.width = 400;
t.height = 400;
t.text = 'Hello';
addChild(t);
使用後

いちぎょーん

addChild(new TextField()._merge({ x: 10, y: 10, width: 400, height: 400 , text: 'Hello'}));

ね!簡単!

わーい