Search code examples
javascriptjqueryfor-loopunassigned-variable

Jquery assignment fails when inside a for loop


I have a jquery which works correctly when I do this:

var slide = [];
slide[1] = 
    {
        hide: function() {
            $("#slide-1").hide();
        },
        show: function() {
            $("#slide-1").show(2000);
        }
    };
slide[1].show(); <<< works fine

But if I try it in a loop in fails:

for (var i=1; i <= totalSlides; i++) {
  slide[i] = 
    {
        hide: function() {
            $("#slide-" + i).hide();
        },
        show: function() {
            $("#slide-" + i).show(2000);
        }
    };
};
slide[1].show();  << unassigned

any idea?


Solution

  • Well, you're saying that it is "unassigned" but I'm guessing that the function is just not doing what you want.

    This is a common issue. All the functions you're creating in the loop are referencing the same i variable. This means that when the function runs, it is getting the value of i where it was left after the loop finished.

    You need to scope the variable that your functions reference in a new variable environment to retain the value from the loop. To do that, you need to invoke a function, and have that function reference the current i value.

    Like this:

    function generate_functions( j ) {
         //    v----- DO NOT place the opening brace on the next line, after the
        return {              // return statement, or your code will break!!!
            hide: function() {
                $("#slide-" + j).hide();
            },
            show: function() {
                $("#slide-" + j).show(2000);
            }
        };
    }
    
    var slide = [];
    
    for (var i=1; i <= totalSlides; i++) {
    
        slide[i] = generate_functions( i );
    
    };
    
    slide[1].show(); // should work
    

    I created a function called generate_functions(), and invoked it in each iteration, passing i as an argument.

    You'll notice that generate_functions() received the value as the j parameter. You could call it i as well, but changing the name makes it a little clearer IMO.

    So now your functions are referencing the local j. Because a new variable environment is created with each invocation of generate_functions(), the functions inside that you create will be referencing the j value of that specific variable environment.

    So the generate_functions() returns the object that contains the functions that were created in each new variable environment, and that object is assigned to slide[i].