0
for (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);
}

Since the nested function is a closure it has a reference to the num argument ,the num argument at the end of the loop is 4 .Now when the first element gets clicked why does it alerts 1 ?It should alert 4 .What is the reason for alerting 1 ?Dont it reference to num argument?or what is the reason?

But here the case is different:

function foo(x) {
 var tmp = 3;
 return function (y) {
 alert(x + y + (++tmp));
 }
}
var bar = foo(2); // bar is now a closure.
bar(10);

The above function will alert 16, because bar can still refer to arg x and tmp, even though it is no longer directly inside the scope.

This proves that the closure also have reference to arguments value than why the above code not alerting 4 everytime?

BenMorel
37k52 gold badges208 silver badges339 bronze badges
asked Apr 3, 2013 at 17:48
3
  • 3
    It's alerting 1 when clicking on the first element since you are passing the argument i at the current iteration to the inner onclick function which has the argument num. Commented Apr 3, 2013 at 17:50
  • 1
    This question on SO has some great answers that can help you understand closures Commented Apr 3, 2013 at 17:53
  • 1
    It actually should be alerting 0, since thats the first # that you pass Commented Apr 3, 2013 at 17:57

2 Answers 2

3
 for (var i=0, link; i<5; i++) { //i starts at 0 and iterates up to 4
 link = document.createElement("a");
 link.innerHTML = "Link " + i;
 link.onclick = function (num) {
 //num is never changed within this function, and is equal
 //to the value of i when it was passed in
 return function () { alert(num);};
 }(i); //i is passed here
 //that sets num to the current value of i for each link
 document.body.appendChild(link);
 }

For the first link num will be 0, because i was one when it was passed to the outer function. i is then iterated for each turn of the loop and will be a different value for each link.

The pattern here is a very common pattern for preserving the current value of a loop iteration in callbacks/event bindings.

answered Apr 3, 2013 at 17:54
Sign up to request clarification or add additional context in comments.

2 Comments

so wont the event handler reference to the arg num on the first click?
yes. and num is preserved by the closure to be the value of i when the onclick property was first set.
0

What you're doing is the classic example to avoid that clicking on the first element will give you 4 instead of 1, which should be the most expected value.

If you want it to alert 1, then just do this:

link.onclick = function() {alert(i);};

But honestly, what would be the point of this? All 4 links would alert 4...

answered Apr 3, 2013 at 17:56

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.