我正在寻求帮助,因为我不认为我理解Javascript范围规则。我在下面的示例中尝试做的是按一个页面上的按钮,然后开始监听键盘输入。一旦键盘输入开始,如果输入中断两秒钟,我想停止捕获输入并弹出一个警报,其中包含收集到该点的输入的全部内容。这是我纯粹为这个问题做的一个例子。
我看到的是单击按钮并开始输入输入。在每个按键时,我都会收到收集到该点的字符串。在两秒钟之后,发生无动作超时我看到内容为“未定义”的警报。上面列出的第一个警报来自startLog()。第二个警报来自stopLog()。当我调用stopLog告诉我this.message未定义时,我做错了什么?
function Logger() {
this.message = '';
this.listenTimer;
this.startLog = function() {
this.message = '';
$(document).bind('keypress', {this_obj:this}, function(event) {
event.preventDefault();
var data = event.data;
clearTimeout(data.this_obj.listenTimer);
data.this_obj.message += String.fromCharCode(event.which);
alert(data.this_obj.message);
data.this_obj.listenTimer = setTimeout(data.this_obj.stopLog, 2000);
});
};
this.stopLog = function() {
$(document).unbind("keypress");
alert(this.message);
};
}
var k = new Logger();
$('.logging-button').click(function() {
k.startLog();
});
答案 0 :(得分:0)
问题是this
。将对象方法作为事件处理程序传递时,它会丢失其对象上下文; this
将引用window
对象。
有多种方法可以解决这个问题,但主要问题是你需要传递setTimeout
一个仍然会引用正确上下文的闭包:
setTimeout(function() { data.this_obj.stopLog() }, 2000);
另外,您可以通过使用闭包引用对象来保存自己一些不必要的代码,而不是将其绑定为event.data
:
this.startLog = function() {
this.message = '';
var this_obj = this;
$(document).bind('keypress', function(event) {
event.preventDefault();
clearTimeout(this_obj.listenTimer);
// etc
});
};
答案 1 :(得分:0)
var k = new Logger();
$('.logging-button').click(function() {
k.startLog.apply(this);
//Setting context of "this" so that it refers to element even in startLog()
});