1

In the following snippet, why and how does the calling the function form a brand new execution context where the value of i is retained?

function getHandler(n) {
    return function() {
        alert( 'You clicked on: ' + n );
    };
}
 
for (var i = 0; i < 100; ++i) {
    myElements[i].onclick = getHandler(i);
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Rose Perrone
  • 61,572
  • 58
  • 208
  • 243
  • I'm assuming you mean why and how does calling the function *from within the loop* form a brand new... etc etc? – Ben Lesh May 23 '12 at 03:23
  • Sounds like some sort of homework to me. If not - then the reason for that is closure that is created for `getHandler` function scope when a new anonymous function is created. The function reference is then returned and the value if `n` retained, due to closure. – ZenMaster May 23 '12 at 03:27

1 Answers1

2

It's caused by JavaScript closures and the behavior of variables declared in a for loop in JavaScript. Because the argument n is part of addHandler's closure, n maintains it's value for the function instances declared inside of itself. It just so happens that your passing in i from a for loop in the global space.

Here is a fiddle showing that behavior.

If you were to do something to increment n inside of addHandler, you would see that it doesn't actually effect i. Once again, this is because of closure, n exists inside of addHandler's closure and was merely populated by i.

Here is a fiddle showing that behavior.

Because of closure, n will exist for however long whatever is created inside of addHandler (in this case some function references) exist.

I hope that makes sense. It's tricky to explain, I think.

EDIT: Here is an awesome explanation of JavaScript closures and how they work.

Community
  • 1
  • 1
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • Thanks! That makes sense. How does the "closing over" of a function happen? That is, when you define a function that returns a function, that inner function has access to the properties of the outer function at the execution time of the outer function. But as soon as the inner function is returned and set to a new var outside the outer function, how does it remember the variables from the outer function? – Rose Perrone May 23 '12 at 04:02
  • Or do we always use the inner function by calling the outer function, so it is always executed within the context of the outer function? – Rose Perrone May 23 '12 at 04:06
  • 1
    The best thing to do is look at the brackets {}... If something is *declared* inside the outer brackets of a function, it's going to be available for anything else declared inside of those same brackets. – Ben Lesh May 23 '12 at 13:19