1

I have an array of elemens, it is populated but all the members are undefined.

// Result: [div.some-class, div.some-class, div.some-class, div.some-class]
console.log(myArray);

// Result: 4
console.log(myArray.length);

for(var i = 0 ; i < myArray.length; i++) {
    setTimeout(function() {

        console.log(myArray[i]); // <- This is "undefined"
        console.log(myArray);    // <- Successful log: has access to array
        console.log(i);          // <- Successful log: has access to "i"

        // Uncaught TypeError: Cannot read property 'classList' of undefined
        myArray[i].classList.add('yeah');  

    }, i * 200);
} 

It works without timeout:

for(var i = 0 ; i < myArray.length; i++) {
    // No errors -> it works
    myArray[i].classList.add('yeah');  
} 

myArray is a global value and timeout has access to every data it needs. Why it's still undefined?

Solo
  • 6,687
  • 7
  • 35
  • 67
  • The value of variable `i` is past the last element when those functions actually run. Your `for` loop completes before they get to run! As you should have seen the value of `i` always is 4 in your output, which is the value after loop completion. – Mörre Jun 30 '16 at 18:56

1 Answers1

1

When the timeout invokes the function, the loop has already ended, which means the i is equal to 4.

Here's an easy fix:

for(var i = 0 ; i < myArray.length; i++) {
    (function(i) {
        setTimeout(function(i) {

            myArray[i].classList.add('yeah');  

        }, i * 200)
    })(i);
} 

You simply invoke the timeout with each i and pass that i to the function

Asaf David
  • 3,167
  • 2
  • 22
  • 38