Why can I not pass a "function declaration" as an argument in an event handler function with JQuery?

494 views Asked by At

Why isn't this working using function declaration, but it's working perfectly using function expression? Assuming that the only difference is how the browser loads them into the execution context.

function foo(event){
    console.log('in foo');
}

$('.btn').on('click',foo(event)); 

$.ajax({
    beforeSend:function(){
        $('btn').unbind('click');
    },
    success: function(){
        $('btn').bind('click', foo(event));
    }
});

With function expressions it works great:

var foo = function(event){
    console.log('in foo');
}
1

There are 1 answers

0
Pointy On BEST ANSWER

Here:

$('.btn').on('click',foo(event)); 

you're not passing a "function expression". You're passing the result of calling the function "foo". That's just the way JavaScript syntax works — if you reference a function (by name or otherwise) and follow that with a parenthesized argument list (possibly empty), you're calling the function.

Here:

var foo = function(event){
    console.log('in foo');
}

you're creating a function, not passing it. Note that in your "foo" example the function keyword is absent.

If you want to pass the function "foo" as an event handler, just reference it by name:

$('.btn').on('click', foo);

That passes a reference to the function "foo" without calling it. The jQuery API will get that function reference and use "foo" as the handler for "click" events.

If you need to pass a reference to a function somewhere (like to a jQuery API), and you want the function to be invoked with some additional parameters, you have two choices:

  1. Use the .bind() method on the Function prototype, or
  2. Wrap the function in another function yourself.

In the case of a jQuery event handler, a third choice is to provide an object as an argument to .on(). That object will be attached to the event parameter passed when the event actually happens:

function foo(event) {
  var data = event.data;
  if (data.whatever) { // ...

Then, when you call .on():

$('.btn').on('click', { whatever: true }, foo);