1

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');
}
Pompeyo
  • 1,459
  • 3
  • 18
  • 42
  • 6
    You realize that `foo(event)` calls the function and passes the return value (`undefined`) to `.bind`? – Jon Dec 12 '13 at 21:21
  • Not really because following this: http://stackoverflow.com/a/336868/2326828, foo(event) is declared in the "code region" (before the program gets executed) isn't it? – Pompeyo Dec 12 '13 at 22:08

1 Answers1

8

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);
David Thomas
  • 249,100
  • 51
  • 377
  • 410
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • @DavidThomas I think you fixed that "has" -> "as" thing right? Looks OK to me I think. :) Also thanks! – Pointy Dec 12 '13 at 21:34