1

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.

yash shukla
  • 49
  • 1
  • 5

3 Answers3

2

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.

Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

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 NaNs

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

Ahmet Can Güven
  • 5,392
  • 4
  • 38
  • 59
  • Yup, this worked. But i am confused how i am already using this reference then what difference did bind(this) made. also if use arrow method like ()=>showtimer() then also it is working. So i need to know why these two methods are working/ – yash shukla Jul 31 '17 at 07:04
  • @yashshukla Explained with more details, edited answer. – Ahmet Can Güven Jul 31 '17 at 07:09
  • I have understood 70% but still confused between this, ()=> and bind(this) not exactly sure about the functionality. do you know any book or blog where i can find good info on this? Thanks a lot for your help – yash shukla Jul 31 '17 at 07:24
  • @yashshukla I could't find a good source for you but you may check https://developer.mozilla.org/tr/docs/Web/JavaScript/Reference/Global_Objects/Function/bind and https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setInterval – Ahmet Can Güven Jul 31 '17 at 07:40
0
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

Tripurari Shankar
  • 3,308
  • 1
  • 15
  • 24