1

I did some digging around on SO and could not find exactly what I am trying to achieve.

In simplistic terms I have a function like

function(){
   for(i=0;i<10;i++){
      setInterval(function(){ alert(i);), 1000)
   }
}

What I would expect is 10 setIntervals that would alert 1 to 10 every 1 second, what happens is it would alert 10 always since 'i' is 10 at the end of for loop. How do I pass 'i' to setInterval anonymous function so that I can preserve the value of i in setInterval?

Above was a simplistic version of my actual problem. I am actually trying to do this var timers = [];

function(obj){
   //Clear any intervals
   for(i=0;i<timer.length;i++){
      clearInterval(timers[i]);
   }

   // Empty timers Array
   timers = [];

   for(i in obj){
      //My object from the dom. This guy is what I am trying to preserve
      my_obj = document.getElementById(i);
      if(obj[i] === "Something"){
         timers.push(setInterval(function(){
            my_obj.replace_class(["Something", "Otherthing"],"Something");
         }, 1000)
      }
   }
}

my_obj in the above code always refers to id = last 'i' in obj.

Do I make sense?

tryurbest
  • 1,419
  • 1
  • 12
  • 22
  • [Once again](http://stackoverflow.com/a/750506/1169519) ; ). – Teemu Dec 30 '13 at 18:03
  • possible duplicate of [Javascript infamous Loop problem?](http://stackoverflow.com/questions/1451009/javascript-infamous-loop-problem) – Dagg Nabbit Dec 30 '13 at 18:08
  • Thanks for the suggestion for already asked questions. I guess I did not understand what my actual problem was so there was no way for me to search for it. – tryurbest Dec 30 '13 at 18:38

2 Answers2

3

This should do the trick ;)

for(i = 1; i < 11; i++){
  (function(local_i){ 
    setInterval(function(){ console.log(local_i); }, 1000 * local_i)
  })(i);
}
Alexander Mikhalchenko
  • 4,525
  • 3
  • 32
  • 56
Chris Gunawardena
  • 6,246
  • 1
  • 29
  • 45
  • The above code has "10 setIntervals that would alert 1 to 10 every 1 second". Am I missing something? – Chris Gunawardena Dec 30 '13 at 18:11
  • I'm not sure, if you had missed something, the question is somewhat vague. Anyway, all the set intervals are "firing" at the same time, hence you will get ten `1`s, ten `2`s etc. Perhaps it's better to use `setTimeout()`? Though this might be intended behavior too. – Teemu Dec 30 '13 at 18:15
  • The code I gave fires 10 setIntervals every 1 seconds but they will print out 1 to 10 every time because it keeps the i values in a local var. – Chris Gunawardena Dec 30 '13 at 18:25
  • Do you want to fire one setInterval every second for 10 seconds? – Chris Gunawardena Dec 30 '13 at 18:26
  • Your answer did the trick. I think this is all about understanding the fundamentals of Javascript, which I am still learning. Thank you. – tryurbest Dec 30 '13 at 18:36
2

You must capture the variable in a closure. In your case this is

function capture(x) {
    setInterval(function () {
        console.log(x);
    }, 1000);
}

for (var i = 0; i < 10; i++) {
    capture(i);
}

or

function capture(my_obj) {
    var id = setInterval(function() {
        my_obj.replace_class(["Something", "Otherthing"],"Something");
    }, 1000);

    return id;
}

for (i in obj) {
    //My object from the dom. This guy is what I am trying to preserve
    my_obj = document.getElementById(i);
    if (obj[i] === "Something") {
         timers.push(capture(my_obj));
    }
}
Community
  • 1
  • 1
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198