Reputation: 49
This is the code i am using to increment intVariable value using window.setinterval.
var Arrow = (function () {
function Arrow() {
this.intVariable = 1;
this.itemId = -1;
this.interval = 25;
}
Arrow.prototype.activateTimer = function () {
if (this.itemId === -1) {
window.setInterval(this.showTimer(), this.interval);
}
};
Arrow.prototype.showTimer = function () {
this.intVariable += this.interval;
console.log(this.intVariable);
};
return Arrow;
}());
var arrow = new Arrow();
arrow.activateTimer();
When I use below line the show timer function is called only once
window.setInterval(this.showTimer(), this.interval);
But when i change it to :
window.setInterval(() => this.showTimer(), this.interval);
It works perfectly.
Need some help why it worked using arrow function.
Upvotes: 1
Views: 95
Reputation: 5462
You should provide function to interval, not the return of the function.
Whenever you write window.setInterval(this.showTimer(), this.interval);
Actually you are doing this
var returnValue = (function () {
this.intVariable += this.interval;
console.log(this.intVariable); // You get your log for once
})() // -> null
window.setInterval(returnValue/*null*/, this.interval);
Then setInterval
tries to call null
after each this.interval
and this won't give you an error on console.
But when you call it with arrow () => this.showTimer()
this means:
var returnValue = function() {
this.showTimer();
} // -> Function
window.setInterval(returnValue/*Function*/, this.interval);
You are providing a function to interval.
And also if you forget to bind your function to this
scope you won't be able access your arrows scope. As a result you may see lots of NaN
s
setInterval
tries to call your registered function with global scope which is window
. So when you write this
in your function it will take this
as window
. So whenever you try to log this.intVariable
it tries to log window.intVariable
which is not defined.
So we should bind our function to current objects scope. So that whenever you use this
, your scope will be binded to your current object (Arrow). And you get get your current arrows intVariable
.
But whenever you write () =>
you create anonymous function like above and you already connect its scope into the object. So you won't need additional binding.
Here is your solution
var Arrow = (function () {
function Arrow() {
this.intVariable = 1;
this.itemId = -1;
this.interval = 25;
}
Arrow.prototype.showTimer = function () {
this.intVariable += this.interval;
console.log(this.intVariable);
};
Arrow.prototype.activateTimer = function () {
if (this.itemId === -1) {
window.setInterval(this.showTimer.bind(this), this.interval);
}
};
return Arrow;
}());
var arrow = new Arrow();
arrow.activateTimer();
Here is a fiddle
Upvotes: 1
Reputation: 386560
You could use directly the function reference (without using parenthesis)
window.setInterval(this.showTimer, this.interval);
By using a function call,
window.setInterval(this.showTimer(), this.interval);
// ^^
you insert the result of the function call and not the function itself.
When you use
window.setInterval(() => this.showTimer(), this.interval);
you insert a function without actually calling it.
Upvotes: 2
Reputation: 3548
window.setInterval(() => this.showTimer(), this.interval);
is like
window.setInterval(function() {this.showTimer()}, this.interval);
window.setInterval(this.showTimer(), this.interval);
not work because you need to only pass the this.showTimer
but you are calling it on the fly
Upvotes: 0