1

I know, great title right ;-)

Anyway, lets say I have the following code (which I do):

function GetArray(i) {
    if (i == 0) {
        return [1, 2, 3];
    }
    return [];
}

for (var i = 0; i < 3; i++) {
    var array = GetArray(i);

    var onClick = function() {
        alert(array.length);
    }

    var html = "<a>click me</a><br/>";
    var element = $(html);
    $("div").append(element);

    element.click(onClick);
}​

See working code here

Click the 3 links, and notice the alert with the value of 0 for each.

What I want is for the first link to alert 3 when clicked.

Now, before you all start shouting why this is happening, I get that the onClick function is clearing using a reference to the same instance of the array, and thus each iteration of the loop "changes" the array, rather than creating a new one, this is why in effect the last array value is used for all click events.

So the question is, what can I do to get the job done?

I thought of trying to "clone" the array inside the function the that didn't work (I used .slice(0)) and probably rightly doesn't work. Plus, I am guessing the it may even just be that the exact same function is being used for all 3 events.

1

1 Answer 1

2

Whenever this happens, its a scoping issue. You need to lock the array in to the onClick handler each time thru the array. You do that by creating a closure around it via a self invoking function.

for (var i = 0; i < 3; i++) {
    var array = GetArray(i), onClick;

    // create a closure around onClick and array
    (function(array){
        onClick = function() {
            alert(array.length);
        }
    })(array);

    var html = "<a>click me</a><br/>";
    var element = $(html);
    $("div").append(element);

    element.click(onClick);
}​

Note this will alert 3, 0, 0, as the second and third time thru the leep you return an empty array.

Sign up to request clarification or add additional context in comments.

2 Comments

...scary... but thanks, makes perfect sense to me, just had no idea how to do it
this happens with timeouts a lot too

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.