I have this piece of code:
class CombatLog {
constructor(){
this.idMsg = 0;
this.timerInterval;
}
startTimer(){
this.timerInterval = setInterval(this.combatStartLog, 2000);
$('#combatLog').empty();
}
combatStartLog(){
console.log(this.idMsg);
switch (this.idMsg){
case 3:
clearInterval(this.timerInterval);
$('#combatLog').empty();
break;
case 2:
$('<p>', {
class: 'combatText',
id: `${this.idMsg}`
}).appendTo('#combatLog');
$(`#${this.idMsg}`).append(`FIGHT!`);
this.idMsg = 3;
break;
case 1:
$('<p>', {
class: 'combatText',
id: `${this.idMsg}`
}).appendTo('#combatLog');
$(`#${this.idMsg}`).append(`Prepare your potions...`);
this.idMsg = 2;
break;
case 0:
$('<p>', {
class: 'combatText',
id: `${this.idMsg}`
}).appendTo('#combatLog');
$(`#${this.idMsg}`).append(`Unsheathe your weapons...`);
this.idMsg = 1;
break;
default:
this.idMsg = 0;
}
}
The desired behavior would be:
startTimer()
combatStartLog()
as an intervalidMsg
of the object falls into the corresponding casecase '3'
clears the interval and breaks the loop.What actually happens:
idMsg
is instantiated as undefined
even though its initial value is set in the constructor:The constuctor
constructor(){
this.idMsg = 0;
this.timerInterval;
}
this.idMsg = 0;
and when it gets to case 3, idMsg is set to 0 but the interval is never cleared and the loop goes on and on and on forever.By passing in the function to the setInterval function, when it is invoked, the 'this' variable loses context. So you need to make sure to bind 'this' of combatStartLog to the instance of CombatLog object:
class CombatLog {
constructor(){
this.idMsg = 0;
this.timerInterval;
this.combatStartLog = this.combatStartLog.bind(this);}}
When you call new CombatLog(), it calls the constructor function with 'this' as the new object being instantiated. By reassigning combatStartLog to combarStartLog bound to the new object, 'this' inside combatStartLog refers to the newly instantiated object.