I was trying to bind an on click event to a table tr in JQuery. The first example below worked as expected however the second one did not. The populate_form function fired without waiting for the event.
I was wondering if someone could explain to me why?
Thanks in advance..
Example One
.click(function() { populate_form(row.name, row.age, row.dob); });
Example Two
.click(populate_form(row.name, row.age, row.dob));
The quick answer, which will probably already be answered and accepted by the time that I post
this answer, is that your second version invokes
populate_formand then passes the result of thefunction to click. Which, in this case, isn’t what you want. What
.click()is really expectingis a reference to a function to execute, when something triggers that event.
That’s the quick answer; which may or may not make sense immediately. So, let’s look a
contrived simple example. Consider the following code:
This is a gross over-simplification of what jQuery is doing, but it gets the point across.
We have a little class, and its got two methods:
setCallbackandgo. Now, the idea isthat when we call
go()we want to execute whatever function we have provided. Also note thatdefault
callbackis set to a function that is empty (ornoop).So if we do this:
Then nothing will happen, but we wont get any errors. That’s because that empty
noopfunction gets invoked.Now we have to talk about the two ways to define a function in JavaScript: A function expression and a function declaration.
A function declration looks like this:
And if we wanted to invoke that function, we would write:
And we would see the alert. However, if we just wanted to reference the function itself (without invoking it), then we would just use its name:
Notice the lack of parentheses; that makes this just a reference to the function. It was never told to do its work, so the alert never appears. Now, let’s look back at our
Fooclass, and more specifically at thesetCallbackfunction:Notice that this method accepts one argument, and assigns it to an property on
this. Basically, we want to save a reference to a functionfor later use. And lets look at the
gomethod as well:This takes whatever is stored in
this.callbackand tries to invoke it using,.apply(), we could have also used.call()(subtle difference between those two). Or would have just saidthis.callback().So lets, look at how it would be used. If I were to write…
…you would not see the popup. However, adding the last line…
… you would see the popup. This is because
go(), invoked the reference tosayHellothat it had kept track of. However, you second example is doing something like this:Notice that you get the popup, however we never called
bar.go(). That is becausesayHello()is invoking the method.The return value from that function is being passed into
setCallback. If we tried to callbar.go(), we would get atype error because we tried to set
callbackto something that wasn’t a function and then tried to invoke it. This isa “bad thing”.
Now, what about function expressions? A function expression is a different way to define a function. Kind of the same way you would define a string or a Number in JavaScript. It has a similar but slightly different form:
This essentially creates a new anonymous function and assigns it to the variable
sayHelloExpression. So we can use it just like out previous example:Or we could skip assigning it to a variable all together and just say:
Now there are some subtle (but important) differences between function declarations and function expressions that other people have gone into in more details about, but the key to understand here is that you can talk about a function, without invoking it. You can also keep track of a reference to a function and then invoke it later.
In your first case you are creating a function expression that is invoking another function with some arguments. Just like our
alertin our function expression, except it is a user defined function. But what you are givingsetCallbackis still a reference to a function that won’t be invoked until later.Lastly, let’s look at a reasonable use to invoke a function using when dealing with a callback like this. An example would be when you have a function that returns another function. Consider this function:
This function takes one argument, and then builds and returns another function.
This function is like a little factory for us to create other functions with. In this case, it makes total sense for use to invoke this function when using it with our
setCallbackmethod, because we want to set the callback to the result of the function that we are invoking. Something like this.There is plenty more to learn, but that’s my long answer to this question.