Monday, 11 April 2016

JavaScript click handler not working as expected inside a for loop





I'm trying to learn JS and got an issue.



I tried many things and googled but all in vain. Following piece of code doesn't work as expected. I should get value of i on click but it always returns 6. I'm pulling my hair out., please help.



for (var i = 1; i < 6; i++) {


console.log(i);

$("#div" + i).click(
function() {
alert(i);
}
);
}



jsfiddle


Answer



Working DEMO



This is a classic JavaScript closure problem. Reference to the i object is being stored in the click handler closure, rather than the actual value of i.



Every single click handler will refer to the same object because there’s only one counter object which holds 6 so you get six on each click.



The workaround is to wrap this in an anonymous function and pass i as argument. Primitives are copied by value in function calls.




for(var i=1; i<6; i++) {
(function (i) {
$("#div" + i).click(
function () { alert(i); }
);
})(i);
}



UPDATE



Updated DEMO



Or you can use 'let' instead var to declare i. let gives you fresh binding each time. It can only be used in ECMAScript 6 strict mode.



'use strict';

for(let i=1; i<6; i++) {


$("#div" + i).click(
function () { alert(i); }
);
}

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...