user1883050 user1883050 - 3 months ago 7
Javascript Question

javascript - seeking satisfying explanation of why anonymous function wrapper needed in callbacks

I know that this works:

$("#btn_1").click(function() {
alert("Btn 1 Clicked");
});


While this just pops up the alert dialog prematurely:

$("#btn_1").click(alert("Btn 1 Clicked"););


My Q is: in the second case, why doesn't the alert wait for the click before executing?

Answer

Because when you call a function, the arguments are executed immediately to provide the parameters to pass to the function.

func(arg);

is equivalent to:

var temp = arg;
func(temp);

So when you write:

$("#btn_1").click(alert("Btn 1 Clicked"));

it's equivalent to:

var temp = alert("Btn 1 Clicked");
$("#btn_1").click(temp);

It should be obvious that in this form, the alert happens before calling .click() to add a listener for the event.

In order to delay action, you have to provide a function as the argument. A function definition by itself doesn't cause any of the code to be executed, it only gets executed when it gets called later (this is called a "callback").

It doesn't have to be an anonymous function, you can name it as well.

function myAlert() {
    alert("Btn 1 Clicked");
}
$("#btn_1").click(myAlert);

But notice that you just provide the name of the function as the argument to .click(), you don't write myAlert(), because that will call it immediately, not delay until the click event occurs.

As @Titus said, click() expects its argument to be a function, because it wants to execute it as a callback. But you can call another function to return a function:

function alerter(message) {
    return function() {
        alert(message);
    }
}
$("#btn_1").click(alerter("Btn 1 Clicked"));

Notice that alerter() doesn't call alert() directly, it returns another function that will call alert() when it is called. As above, that won't happen until the click event performs its callback.