Functionコンストラクタを使ってJavaScriptネイティブじゃない関数をラッピングする方法

ExternalInterface.addCallback で定義された関数は apply できない
http://d.hatena.ne.jp/nitoyon/20070214/p1

っていう記事に書いてあるコードを手直し。Flashをいじってないんで、上手く動くかどうかよくわかんないですが、こんな感じでいけると思います。
function applySwf(swf, method, args){
    if(swf && typeof swf[method] == "function"){
        var params = [];
        for(var i=0;i<args.length;i++) params[i] = "_"+i;
        Function(
            params.join(','),
            "this("+params.join(',')+")"
        ).apply(swf[method], args);
    }
}

args.lengthが4の場合は
(function anonymouse(_0,_1,_2,_3){this(_0,_1,_2,_3)}).apply(swf[method], args);

というコードが動的に生成されるので、引数がいくつになっても対応できます。

汎用化するとこんな感じに。ただのサンプルコードなので利用はご自由にどうぞ。
Function.toNative = function(obj, method_name){
    return function(){
        var params = [];
        for(var i=0;i<arguments.length;i++) params[i] = "_"+i;
        return Function(
            params.join(','),
            'this["'+method_name+'"]('+params.join(',')+')'
        ).apply(obj, arguments);
    }
}
document.write.apply(document,[1,2,3]); // IEだとエラー
var dw = Function.toNative(document,"write");
dw.apply(null, [1,2,3]); // 123と表示

IEではdocument.writeやwindow.alertなどのブラウザの機能を呼び出す組み込み関数では、JavaScriptのFunction.prototypeを使うことができません。そのような場合に、こういった形でラッピングした関数を作ってやれば、自前で定義したFunction.prototypeが使用でき、かつ、元の関数の機能を損なわない関数に変形してやることができます。

参考
IEでXMLHttpRequestを使えるようにする
http://la.ma.la/blog/diary_200509031529.htm


WriteBacks

typo

いつも楽しみにしています。
anonymouse->anonymous

Posted by aoi at 2007/02/16 (Fri) 14:11:18

re: typo

そうですね。

ma.la the typo generater

Posted by mala at 2007/02/16 (Fri) 15:03:10

Posted by at 2007/04/17 (Tue) 17:07:07
TrackBack ping me at
http://la.ma.la/blog/diary_200702152107.trackback
Post a comment

writeback message: Ready to post a comment.







spam yoke. nanimo ireruna.