techkuz
techkuz

Reputation: 3956

Closure counter inside setInterval

I have a function:

setInterval(function () {
        var counter = 0;
        (function() {
          counter = counter + 1;
          console.log(counter);
          })(counter)
       }, 1000)

Why does not it increment the counter? (instead, it logs 1's). How to make it log ascending numbers? (1, 2, 3, ....)

Upvotes: 2

Views: 2912

Answers (3)

Quentin
Quentin

Reputation: 943510

  1. You are passing an argument to your anonymous function, but you aren't assigning that argument to a variable. You forgot to put the arguments in the function definition.
  2. You are creating new variables with every iteration instead of sharing the variable between them. You need to turn your logic inside out.

(function(closed_over_counter) {

  setInterval(function() {
    closed_over_counter++;
    console.log(closed_over_counter);
  }, 1000);

})(0);

Since you are using an IIFE instead of a function you can call multiple times, this is pretty pointless. You might as well just declare the variable inside the closure.

(function() {
  var counter = 0;
  setInterval(function() {
    counter++;
    console.log(counter);
  }, 1000);
})();

Or, since Internet Explorer is no longer a concern for most people, dispense with the IIFE and use a block instead.

{
  let counter = 0;
  setInterval(function() {
    counter++;
    console.log(counter);
  }, 1000);
}

Upvotes: 5

gil.fernandes
gil.fernandes

Reputation: 14611

Obscured version of Nina Scholz's answer with arrow functions:

setInterval(((counter) => () => console.log(++counter))(0), 1000);

Upvotes: 2

Nina Scholz
Nina Scholz

Reputation: 386560

You could use a function which returns a function as closure over counter.

setInterval(function(counter) {
    return function() {
        console.log(++counter);
    };
}(0), 1000);

Upvotes: 5

Related Questions