javascript - this.method 不适用于 setInterval
问题描述
我有这个简单的代码:
var Modules = (function() {
'use strict';
return {
TIMER: function (){
var timer = null;
return {
time: 100,
init: function() {
this.counter();
this.timer = window.setInterval(this.counter, 1000);
},
counter: function() {
this.time -= 1;
if (this.time <= 0) {
window.clearInterval(this.timer);
alert('Time expired');
}
console.log(this.time);
this.viewer();
},
viewer: function() {
document.getElementById('timer').innerHTML = this.time;
}
}
}
};
}());
Modules.TIMER().init();
<div id="timer"></div>
出了点问题,因为我遇到了 2 个错误:
this.viewer 不是函数
和
这次的NaN
我的设计模式在间隔上运行有什么问题?
将 TIMER 扩展为重置方法后:
reset: function() {
this.time = 100;
}
并在外面称它为:
Modules.TIMER().reset();
?
我有
this.time 未定义
.
或在init内部:
jQuery("body").on('keyup mouseup', function (e) {
this.reset();
});
我收到错误:
this.reset() 不是函数。
解决方案
您的问题来自这一行:
this.timer = window.setInterval(this.counter, 1000);
当您在setInterval
方法中调用回调时this
,回调函数中的 不再引用您的TIMER
对象,而是window
.
解决方案 A:.bind(this)
用于将词法绑定this
到回调
您需要将当前上下文绑定到回调:
this.timer = window.setInterval(this.counter.bind(this), 1000);
var Modules = (function() {
'use strict';
return {
TIMER: function (){
var timer = null;
return {
time: 100,
init: function() {
this.counter();
this.timer = window.setInterval(this.counter.bind(this), 1000);
},
counter: function() {
this.time -= 1;
if (this.time <= 0) {
window.clearInterval(this.timer);
alert('Time expired');
}
console.log(this.time);
this.viewer();
},
viewer: function() {
document.getElementById('timer').innerHTML = this.time;
}
}
}
};
}());
Modules.TIMER().init();
<div id="timer"></div>
setInterval
解决方案 B:在回调中使用 ES6 箭头函数
注意:我个人更喜欢这个解决方案,因为它使用 ES6,但是如果你仍然支持旧版浏览器并且不想转译你的 JS,这可能不是最好的解决方案。
另一种选择是在 的回调中使用箭头函数setInterval
,而不是this.counter
直接将函数分配为回调:
this.timer = window.setInterval(() => this.counter(), 1000);
箭头函数保留词法this
,所以当this.counter()
被调用时它将使用相同的上下文,即内部this
将引用您的TIMER
对象。
var Modules = (function() {
'use strict';
return {
TIMER: function (){
var timer = null;
return {
time: 100,
init: function() {
this.counter();
this.timer = window.setInterval(() => this.counter(), 1000);
},
counter: function() {
this.time -= 1;
if (this.time <= 0) {
window.clearInterval(this.timer);
alert('Time expired');
}
console.log(this.time);
this.viewer();
},
viewer: function() {
document.getElementById('timer').innerHTML = this.time;
}
}
}
};
}());
Modules.TIMER().init();
<div id="timer"></div>
推荐阅读
- r - 为什么由 as_adjacency_matrix(g) 生成的无向图矩阵有时会显示 2 而不是 0 或 1 的条目?
- python-3.x - Prometheus pushgateway Counter inc 不正确
- javascript - 是否有正则表达式来匹配无法呈现任何文本的 html 字符串?
- android - 将 Key 添加到 BuildConfig 并在 @header kotlin 中调用它
- c++ - 谷歌测试中的 EXPECT_NO_DEATH()
- php - ajax 文件名作为二进制发送
- webassembly - Wasmer 中的“将其嵌入其他语言”是什么意思?
- java - 为什么我在使用 Retrofit 和 GSON 转换器映射的对象属性上得到空值?
- c# - 提交时的 ASP.NET MVC C# 电子邮件通知
- windows - NTUSER reg 条目不会反映在当前用户中