jQuery.proxy() usage
When you want a function that has the this
value bound to a specific object. For example, in callbacks such as event handlers, AJAX callbacks, timeouts, intervals, custom objects, etc.
This is just a manufactured example of a situation where it might be useful. Assuming there is a Person
object which has a property name. It is also linked to a text input element, and whenever the input value changes, the name in this person object gets updated too.
function Person(el) {
this.name = '';
$(el).change(function(event) {
// Want to update this.name of the Person object,
// but can't because this here refers to the element
// that triggered the change event.
});
}
One solution that we often use is to store the this context in a variable and use that inside the callback function such as:
function Person(el) {
this.name = '';
var self = this; // store reference to this
$(el).change(function(event) {
self.name = this.value; // captures self in a closure
});
}
Alternatively, we could have used jQuery.proxy
here so the reference to this
refers to the object of Person instead of the element that triggered the event.
function Person(el) {
this.name = '';
$(el).change(jQuery.proxy(function(event) {
this.name = event.target.value;
}, this));
}
Note that this feature has been standardized into ECMAScript 5 which now includes the bind
method borrowed from prototypejs and is already available on some browsers.
function Person(el) {
this.name = '';
$(el).change(function(event) {
this.name = event.target.value;
}.bind(this)); // we're binding the function to the object of person
}
It's just a shorthand method of setting the context for a closure, for example:
$(".myClass").click(function() {
setTimeout(function() {
alert(this); //window
}, 1000);
});
However often we want this
to remain the same as the method we were in, which $.proxy()
is used for, like this:
$("button").click(function() {
setTimeout($.proxy(function() {
alert(this); //button
}, this), 1000);
});
It's usually used for delayed calls, or anywhere you don't want to do a longhand method of declaring a closure. The string method of pointing the context to an object...well I haven't come across a practical use in every day code yet, but I'm sure there are applications, just depends what your object/event structure is.
For example if you want to create callbacks. Instead of:
var that = this;
$('button').click(function() {
that.someMethod();
});
you can do:
$('button').click($.proxy(this.someMethod, this));
Or if you create a plugin that accepts callbacks and you have to set a specific context for the callback.