jQuery API

jQuery.proxy()

jQuery.proxy( function, context ) Returns: Function

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

  • version added: 1.4jQuery.proxy( function, context )

    functionThe function whose context will be changed.

    contextThe object to which the context (`this`) of the function should be set.

  • version added: 1.4jQuery.proxy( context, name )

    contextThe object to which the context of the function should be set.

    nameThe name of the function whose context will be changed (should be a property of the 'context' object.

This method is most useful for attaching event handlers to an element where the context is pointing back to a different object. Additionally, jQuery makes sure that even if you bind the function returned from jQuery.proxy() it will still unbind the correct function, if passed the original.

Example:

Enforce the context of the function.

var obj = {
  name: "John",
  test: function() {
    alert( this.name );
    $("#test").unbind("click", obj.test);
  }
};

$("#test").click( jQuery.proxy( obj, "test" ) );

// This also works:
// $("#test").click( jQuery.proxy( obj.test, obj ) );

Comments

  • Support requests, bug reports, and off-topic comments will be deleted without warning.

  • Please do post corrections or additional examples for jQuery.proxy() below. We aim to quickly move corrections into the documentation.
  • If you need help, post at the forums or in the #jquery IRC channel.
  • Report bugs on the bug tracker or the jQuery Forum.
  • Discussions about the API specifically should be addressed in the Developing jQuery Core forum.
  • deer421
    I am a bit perplexed why this function was not designed to take 'context' consistently as the first argument. It will avoid any confusion and be more object oriented like if it was:

    jQuery.proxy( context, function )
    jQuery.proxy( context, name )
  • That would also be consistent with .call() and .apply() where context is the first param. That would make the syntax easier to remember.
  • How about adding arguments like this:

    proxy = function( fn, scope ) {
    return function() {
    return fn.apply( ( scope || window ), Array.prototype.slice.call( arguments ) );
    };
    },
  • Your event handlers will be called with the same arguments that they've always been called with. All that .proxy() gives you is the ability to set the execution context (the "this") of those callbacks. To get the element that triggered the event you'll use event.currentTarget.

    function Foo() {
    $('button').click($.proxy(this.handleClick, this));
    }
    Foo.prototype = {
    handleClick: function(event) {
    assert(this instanceof Foo); // true
    assert(event.currentTarget.is('button')); // true
    }
    };
  • I think the word "scope" isn't the correct way of describing what this function does. "Scope" usually refers to the entirety of all variables the current function has access to (in the case of lexical scoping that JavaScript uses, this includes -- simplified -- all identifiers that were defined before/above the current line of code. What this function actually does is to change `this`, also known as the context.
  • Good call, I've updated the documentation to represent that.
  • azoff
    ditto. that's why I call it "context" in my plugin :)
  • azoff
    In case anyone is interested, I added the ability to pass extra arguments (currying) to jQuery.proxy by means of an extension. You can grab the file here (production | development) and read more about it here. The function signature is exactly the same but I overloaded it to accept any arguments (less the first two) as the arguments to pass to the bound function.
  • emmecinque
    Awesome, thanks; without the pseudo-currying "proxy" is really only a half-solution.

    [edit] whoa - actually I'm seeing that if I add in your "proxy" version then lots of stuff quits working; it's hard to tell exactly what through the fog of minification ... I see the errors however even if my own code never calls "$.proxy()".
  • This should be extended so you can also pass in extra arguments to the function (which will get appended to the existing arguments)