68

I was reading the api about jQuery.proxy(). It looks promising but I was wondering in what situation is this best use. Can anyone enlighten me?

Machavity
  • 28,730
  • 25
  • 78
  • 91
Reigel
  • 61,807
  • 21
  • 115
  • 133

3 Answers3

139

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 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
}
Machavity
  • 28,730
  • 25
  • 78
  • 91
Anurag
  • 132,806
  • 34
  • 214
  • 257
  • 34
    +1 for mentioning that this has found its way into ECMAscript. – Mike Sherov Jul 28 '10 at 03:05
  • 1
    Is is *better* (faster, more efficient) to use a regular closure, or to use $.proxy? – Anson MacKeracher Mar 21 '12 at 15:58
  • 4
    @AnsonMacKeracher it is better and faster not to use a closure at all but a proxied static function. These answers don't show that proxy can be used with static functions where as the `self = this` hack can only be used if you create the function inline – Esailija Jul 05 '12 at 15:31
  • 3
    Just to go one step further, in ECMAScript 6 (ES6) Arrow Functions are the way to go (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) ` function Person(el) { this.name = ''; $(el).change((event) => { this.name = event.target.value; }); } ` – TypingTurtle Aug 18 '16 at 12:45
17

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.

Nick Craver
  • 594,859
  • 130
  • 1,270
  • 1,139
14

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.

Felix Kling
  • 705,106
  • 160
  • 1,004
  • 1,072