Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable scoping and event handler

Please see the jsfiddle: http://jsfiddle.net/LsNCa/2/

function MyFunc() {

    for (var i = 0; i < 2; i++) { // i= 0, 1
        var myDiv = $('<div>');
        
        myDiv.click(function(e) {
            alert(i);    // both the two divs alert "2", not 0 and 1 as I expected
        });
        $('body').append(myDiv);
    }
}

var myFunc = new MyFunc();

I want the divs to alert "0" and "1" respectively when I click them, but both of them alert "2".

When I click the divs and the event is triggered, how and where do the handler find the value of the variable i?

I'm aware that adding a closure achieves my goal. But why?

like image 333
Boyang Avatar asked Jul 16 '13 07:07

Boyang


People also ask

What is the role of event handlers?

In programming, an event handler is a callback routine that operates asynchronously once an event takes place. It dictates the action that follows the event. The programmer writes a code for this action to take place. An event is an action that takes place when a user interacts with a program.

What is the difference between an event trigger and event handler?

trigger is a behavior in response to stimuli, and an event may trigger the change of state or as the result of that trigger execute the associated callback . handler is a reference to an object or class that is associated with a behavior.

When would you use an event handler?

Use the EventHandler delegate for all events that don't include event data. Use the EventHandler<TEventArgs> delegate for events that include data about the event. These delegates have no return type value and take two parameters (an object for the source of the event and an object for event data).


2 Answers

    function MyFunc() {

    for (var i = 0; i < 2; i++) { // i= 0, 1
        (function(j) {
            var myDiv = $('<div>');

            myDiv.click(function(e) {
                alert(j);
            });
            $('body').append(myDiv);
        })(i);
    }
}

var myFunc = new MyFunc();

The code above is how you get it work correctly. Without an closure, you always the the last value of i. What we do is to post i into the closure and let the runtime "remember" the value of that very moment.

like image 94
yaoxing Avatar answered Sep 20 '22 10:09

yaoxing


You need a closure because all your event handler functions are referencing the same variable i. The for loop updates this, and when the loop is done the variable contains 2. Then when someone clicks on one of the DIVs, it accesses that variable.

To solve this, each event handler needs to be a closure with its own variable i that contains a snapshot of the value at the time the closure was created.

like image 45
Barmar Avatar answered Sep 19 '22 10:09

Barmar