我有一个像这样定义的对象:
Blah = {
hideTimer:null,
setTimer: function() {
this.hideTimer = window.setTimeout(Blah.hidePopupInner, 500);
// must be done via window due to Greasemonkey
},
hidePopupInner: function() {
log("This? " + this);
},
hidePopupInnerPublic: function() {
Blah.hidePopupInner();
}
}
问题是killTimer中的'this'是而不是设置为Blah。如果我改变行说
this.hideTimer = window.setTimeout(Blah.hidePopupInnerPublic, 500);
然后'this'指向Blah,因此可以使用hideTimer。
为每种方法制作一个“公共”方法可以解决问题,但必须有一个更简单的解决方案......?
注意:这一切都在Greasemonkey中,但我认为这是一个普遍的Javascript问题。
答案 0 :(得分:6)
要解决此问题,您可以在构建超时时使用匿名函数和范围引用。
(code...)
setTimer: function() {
var _this = this;
this.hideTimer = window.setTimeout(function(ms){
_this.hidePopupInner();
}, 500);
},
(code...)
PS:此外,setTimeout将传递毫秒数到调用函数。例如:假设你的函数可以接收一个参数,并用它做一些事情。但是因为setTimeout会将毫秒传递给你的函数,所以会导致意外错误。
答案 1 :(得分:2)
基本上指定为setTimeout param的函数就像回调一样执行 你没有得到Blah上下文的原因是你切换到setTimeout范围(即使使用Blah方法)。
我根本不了解Greasemonkey,但是使用像 Bind 这样的函数方法会对你有帮助。 如果在GM中没有像bind这样的函数,你可以自己编写它,但是你自己(几行代码) - 可以复制PrototypeJS。 http://www.prototypejs.org/api/function/bind
它基本上执行使用指定的范围准备你的函数:
// inside Blah
setTimeout (Blah.hidePopupInner.bind(this), 500);
实际上,Tableton的解决方案是Bind在飞行中的实施
答案 2 :(得分:1)
虽然不是范围问题的真正解决方案,但您至少可以通过以下方式解决Blah.killTimerPublic
:
window.setTimeout(function(){ Blah.hidePopupInner() }, 500);