-2

I am a JS novice and I was reading about closures, the common issues that arise due to misunderstanding how closures work and the "setting handlers inside a loop" was a pretty good example. I've also seen and understood the ways to get around this, i.e, by calling another function passing the loop variables as arguments and returning a function. Then I tried to take a dip to see if there are any other ways to get around this and I created the following code.

var i;

var inpArr = new Array();

for(i = 0; i < 10; ++i) {
  inpArr.push(document.createElement("input"));
  inpArr[i].setAttribute("value", i);
  inpArr[i].onclick = function() {
    var index = i;
    alert("You clicked " + index);
  }
  document.body.appendChild(inpArr[i]);
}

It doesn't work which I guessed but I don't understand why. I understand i was captured and made available to all the function expressions generated. But why does this still not work after assigning the captured variable to the local variable index? Isn't assigning i the same as passing i as an argument to another function? I mean, isn't i a primitive and isn't it supposed to be copied?

I am confused and I would really appreciate it if someone could tell me what's going on here.

sangeeth96
  • 1,202
  • 1
  • 11
  • 20
  • Value of `index` will be `i` every time you click it and value of `i` is `9` as `click` handler is invoked only after `loop` is over..Try this: https://jsfiddle.net/rayon_1990/sgtgfk8s/ – Rayon Apr 01 '16 at 06:11

1 Answers1

1

I think you are expecting that var index = i; is being executed in every iteration of the loop, there by setting different values for different index variables, which is not what happens. During each iteration only the function is assigned to the handler, the function is not run.

this sentence gets executed only when you click, by that time the value of i is already the highest value as per your loop. This exact problem is solved by the solutions you read.

what happens during the loop:

inpArr[0].onclick = <a function>; //(local)index=undefined; i=0;
inpArr[1].onclick = <a function>; //(local)index=undefined; i=1;
inpArr[2].onclick = <a function>; //(local)index=undefined; i=2;
inpArr[3].onclick = <a function>; //(local)index=undefined; i=3;
.
.
inpArr[9].onclick = <a function>; //(local)index=undefined; i=9;

and when you click

index = i; //i=9; (local)index=9;
sabithpocker
  • 15,274
  • 1
  • 42
  • 75
  • Ah. Snap! Should've thought more about it. Yes, I got it confused with executing the declaration every single time. Thanks. – sangeeth96 Apr 01 '16 at 06:15