我有一个案例,我有一个对象,“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()
时我不再有关于回调来自何处的信息。那么有另一种方法来计算上下文(比如在回调函数本身内)吗?
答案 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();
答案 2 :(得分:0)
我会用闭包来做。
foo.doStuff = function(){
bar.callback();
};
如果您担心在创建回调的那一刻和执行回调的那一刻之间bar的值发生了变化,您可以“锁定”bar的值,但这可能有点过分
foo.doStuff = (function(bar){
return function(){
bar.callback();
}
})(bar);