closures - Javascript infamous Loop issue? -


this question has answer here:

i've got following code snippet.

function addlinks () {     (var i=0, link; i<5; i++) {         link = document.createelement("a");         link.innerhtml = "link " + i;         link.onclick = function () {             alert(i);         };         document.body.appendchild(link);     } } 

the above code generating 5 links , bind each link alert event show current link id. doesn't work. when click generated links "link 5".

but following codes snippet works our expectation.

function addlinks () {     (var i=0, link; i<5; i++) {         link = document.createelement("a");         link.innerhtml = "link " + i;         link.onclick = function (num) {             return function () {                 alert(num);             };         }(i);         document.body.appendchild(link);     } } 

the above 2 snippets quoted here. author's explanation, seems closure makes magic.

but how works , how closure makes work beyond understanding. why first 1 doesn't work while second 1 works? can give detailed explanation magic?

thanks.

quoting myself explanation of first example:

javascript's scopes function-level, not block-level, , creating closure means enclosing scope gets added lexical environment of enclosed function.

after loop terminates, function-level variable has value 5, , that's inner function 'sees'.

in second example, each iteration step outer function literal evaluate new function object own scope , local variable num, value set current value of i. num never modified, stay constant on lifetime of closure: next iteration step doesn't overwrite old value function objects independant.

keep in mind approach rather inefficient 2 new function objects have created each link. unnecessary, can shared if use dom node information storage:

function linklistener() {     alert(this.i); }  function addlinks () {     for(var = 0; < 5; ++i) {         var link = document.createelement('a');         link.appendchild(document.createtextnode('link ' + i));         link.i = i;         link.onclick = linklistener;         document.body.appendchild(link);     } } 

Comments