我有这个简单的代码:
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();
吗?
我知道了
此时间未定义
。
或在init内部:
jQuery("body").on('keyup mouseup', function (e) {
this.reset();
});
我遇到错误:
this.reset()不是函数。
答案 0 :(得分:6)
您的问题来自此行:
this.timer = window.setInterval(this.counter, 1000);
当您使用setInterval
方法调用回调时,回调函数中的this
不再引用您的TIMER
对象,而是引用window
。
.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
回调中使用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>
答案 1 :(得分:-1)
我从外面找到了重置的答案。 我这样更改了TIMER:
TIMER: (function (){
// all stuff
}())
然后调用类似于:Modules.TIMER.reset();
,然后按预期方式运行。