Search code examples
javascriptdom-events

JavaScript function within loop / closure


I'm new to JavaScript and trying to understand the behavior of this code, which attempts to assign unique onclick handlers to different DOM elements in the array myElements[]:

(function handleClicks(){
for (var i = 0; i < 100; ++i) {
myElements[i].onclick = function() {
        alert( 'You clicked on: ' + i );
};
})();

My understanding is that each time a DOM element is clicked, the browser should alert 'You clicked on 100' as JavaScript will use the value i has once the function has completed

I have two questions:

  1. If i only has scope within the function handleClicks() how can the browser access i once the function has completed - surely i no longer exists?

  2. I tried this code by putting two HTML elements in the array

    var myElements = [];
    myElements.push( document.getElementById('1');
    myElements.push( document.getElementById('2');
    

http://jsfiddle.net/branmong/fS7qE/

But when the program runs, it alerts 'you clicked on: 2' for each element clicked.

Why isn't it alerting 'you clicked on: 100'. as this is surely the value of i once the function has finished running?


Solution

  • "If i only has scope within the function handleClicks() how can the browser access i once the function has completed - surely i no longer exists?"

    The i variable is in the enclosing scope (the handleClicks function). When a function is created, it carries with it its original variable scope for the life of the function. This is called closure.

    Because of this, all the handler functions created in the loop are referencing the same i variable that exists in handleClicks. This keeps i alive. When you destroy the handlers, i will be able to be garbage collected.


    The second code example stops at 2 because you get a TypeError for accessing a property on undefined. This halts the execution of the code.