Pages

Wednesday, August 1, 2012

jQuery Function Of The Week: proxy

In my JavaScript fundamentals presentations I have a section that talks about scope and how it can become confusing when using jQuery. The reason for this is becuase jQuery normalizes the this scope in its function calls. In other words when inside a jQuery method call this usually refers to the DOM elements in the jQuery set.

This can be clearly illustraed in a simple jQuery event callback (note use your browsers console, not jsbin's for the meantime):

If you run the code you'll see that you get "Hello, undefined" instead of "Hello, Homer Simpson". The reason is simple, jQuery used the link as the context of this where no myName property exists. Enter jQuery.proxy.

According to the jQuery Documentation, the proxy function:

Takes a function and returns a new one that will always have a particular context.

This means that by using the $.proxy function we can make our callback run in the proper context, in this case itself:

The change is subtle, but the result is exactly what we want. Now, at this point you might be asking yourself, "isn't this the same thing as using the apply() or call() methods (mdn apply documentation)? The answer is yes...and no. Lets look at how to get the desired result using apply():

If you look closely you'll notice a slight difference, the callback is now invoked in an anonymous function instead of passed directly to the on() method. This is because the apply method invokes the function immediately whereas jQuery's proxy function only returns a reference function for later invocation. This is a bit nicer because it makes for slightly more terse code.

In addition the proxy() function does a few more things:

it makes sure that the function passed in is actually a function

it assignes a unique ID to the function. This is very important because when trying to unbind a function you may not be unbinding the proper function if you are passing in the function to the off() method. Its best to always use namespaced events when using on() and off() with $.proxy().