从Javascript中的回调内的对象获取上下文

时间:2012-11-21 19:10:35

标签: javascript callback this

我有一个案例,我有一个对象,“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()时我不再有关于回调来自何处的信息。那么有另一种方法来计算上下文(比如在回调函数本身内)吗?

3 个答案:

答案 0 :(得分: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(); };

答案 1 :(得分: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

答案 2 :(得分:0)

我会用闭包来做。

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

如果您担心在创建回调的那一刻和执行回调的那一刻之间bar的值发生了变化,您可以“锁定”bar的值,但这可能有点过分

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