3

別のオブジェクト「bar」でコールバックを呼び出す必要があるオブジェクト「foo」があり、コールバック内のコンテキストが「bar」のコンテキストである必要がある場合があります。ただし、キッカーは、「bar」からコールバックを取得する以外に、「foo」はそれについて何も知らないはずです。

例:

var foo = 
{
    message: "Hello foo",
    doStuff: undefined
};

var bar =
{
    message: "Hello bar",
    callback = function ()
    {
        alert(this.message);
    }

};

foo.doStuff = bar.callback;

foo.doStuff();

通常は「call」または「apply」を使用してコンテキストを bar に切り替えますが、私の特定のケースでは、呼び出し時にfoo.doStuff()コールバックがどこから来たのかに関する情報がありません。では、コンテキストを把握する別の方法はありますか (コールバック関数自体からなど)?

4

3 に答える 3

1

では、コンテキストを把握する別の方法はありますか (コールバック関数自体からなど)?

いいえ。コールバックを渡す前に、いくつかの特別な特定がないわけではありません。関数参照しかない場合は、通常、コンテキストがありません。しかし、いくつかの準備があれば、いくつかの解決策があります。

コールバックをラップできます。これが呼び出さbar.callback()れると、 のコンテキストを維持しながら、完全な形式で呼び出されますbar

foo.doStuff = function() { bar.callback(); };

または、最新の JS エンジンでは、コールバックを特定のコンテキストにバインドできます。

foo.doStuff = bar.callback.bind(bar);

または、underscore.jsを使用して、すべての JS エンジンでそれを行います。

foo.doStuff = _(bar.callback).bind(bar);

または、古いエンジンとの互換性が必要で、ライブラリ全体を使用したくない場合は、独自のバインド関数を作成してください。

var bind = function(fn, context) {
  return function() {
    fn.call(context);
  };
};
foo.doStuff = bind(bar.callback, bar);

とは言っても、通常は単純なラッパーが最も単純で最も一般的です。欠点はほとんどなく、高速で理解しやすく、どの引数で何を呼び出すかを細かく制御できます。この場合、この形式が最も理にかなっていると思います。

foo.doStuff = function() { bar.callback(); };
于 2012-11-21T19:16:53.943 に答える
1

バーにはクロージャーを使用してください。

var foo = {
    message: "Hello foo",
    doStuff: undefined
};

var bar = (function() {
    var message = "Hello bar";
    return {
        callback: function() {                
            alert(message);
        }
    };
})();


foo.doStuff = bar.callback;
foo.doStuff();
​

jsfiddle

于 2012-11-21T19:47:53.907 に答える
0

私はクロージャーでそれをします。

foo.doStuff = function(){
  bar.callback();
};

コールバックを作成してから実行するまでの間に bar の値が変更されるのではないかと心配している場合は、bar の値を「ロック」できますが、それはやり過ぎかもしれません。

foo.doStuff = (function(bar){
  return function(){
    bar.callback();
  }
})(bar);
于 2012-11-21T19:24:35.637 に答える