0

実行時にJavascript関数の実行コンテキストを手動で変更する方法はありますか?

別のオブジェクトを指すように参照を変更することについて話しているのではありませんthisFunction.prototype.call()/apply()

関数にアクセス可能な変数を変更すること、またはより具体的には、関数が定義されているスコープ外の変数へのアクセスを許可することについて話しています。

例:

var func;
(function () {
    func = function () {
        alert(test); // no variable called "test" defined, it will
                     // result in a ReferenceError when func() is called
    }
})();


function callFunction (callee) {
    var test ='foobar';
    callee(); // callee does not have access to "test"
}

callFunction(func);

この例では、関数が呼び出されたときに で定義されfuncた変数にアクセスできるようにしたいと考えています。ただし、スコープと実行コンテキストが Javascript でどのように機能するかにより、そのようには機能しません。testcallFunciton

呼び出しの実行コンテキストでcallFunction呼び出される変数を挿入する方法を探しています。testcallee()


この最小限の例では、test をパラメーターとして func() に追加することはもちろん可能です。

ただし、私のユースケースは、プラグイン インフラストラクチャを備えたフレームワークです。プラグインは、コールバックと、それらが受け取るパラメータをパラメータ タイプとともに指定できます。フレームワークは、要求されたデータを要求された型に変換し、それらをコールバックに提供します。これは、プラグインに対して完全に透過的に発生するはずです。

擬似コード:

プラグイン

function callback {
    alert(user.name);
    alert(number);
};
var callbackParams = [
    {name : 'user', type : User},
    {name : 'number', type : Number}
];
defineCallback('event', callback, callbackParams);

フレームワーク

var on = {
    event : [];
}

var User = function (name) {
    this.name = name;
}

function defineCallback (event, callback, params) {
    on[event].push({
        callback : callback;
        params   : params;
    });
}

function handleEvent(event) {
    on[event].forEach(function (handler) {
        for (param of handler.params) {
            // 1) gather data
            // 2) create Object of correct type as specified in 
            //    param.type
            // 3) insert variable called param.name into 
            //    execution context of handler.callback
        }
        handler.callback();
    });
}

これまでのところ、この問題に対する 3 つの解決策を見つけましたが、どちらも好きではありません。

  • コールバックでパラメーターを定義し、関数宣言での順序でインデックス付けされた callbackParams でそれらの型のみを定義します。欠点: パラメータは 2 つの場所で宣言する必要があります。
  • コールバックthis.paramnameの代わりに使用し、`handleEvent() で使用します。短所: プラグインに対して透過的ではありません。paramname.call()/.apply()
  • handler.callback()呼び出す前に変数をグローバルスコープに割り当て、handleEvent()後で再度削除します。短所:非常に醜い回避策。

アイデア?

4

1 に答える 1

1

withステートメントを使用できます。厳密モードでは遅く、禁止されていることに注意してください。

var func;
(function () {
  func = function func() {
    with(func.variables) {
      console.log(test);
    }
  }
})();
function callFunction (callee) {
  callee.variables = {test: "foobar"};
  callee();
  callee.variables = null;
}
callFunction(func);

于 2016-06-04T18:58:29.660 に答える