jQuery.proxy() takes a function and returns a new one that always runs with a fixed this value. This tutorial covers both official signatures, partial argument application, event-handler binding, safe unbinding with namespaces, migration to Function.prototype.bind(), and pitfalls every beginner should know.
01
Syntax
$.proxy(fn, ctx)
02
By name
$.proxy(obj, "m")
03
Fix this
Event handlers
04
Partial
Pre-fill args
05
.bind()
Native replace
06
Deprecated
Since jQuery 3.3
Fundamentals
Introduction
In JavaScript, the value of this depends on how a function is called — not where it is defined. When you pass an object method to a jQuery event handler, this inside that method usually becomes the DOM element that was clicked, not your object. That breaks code expecting this.name or this.save().
jQuery added jQuery.proxy() in version 1.4 to lock this to a chosen object. It was deprecated in 3.3 in favor of the native Function.prototype.bind(), but remains widely used in legacy plugins and tutorials. Understanding $.proxy() also teaches the same context problem that arrow functions and .bind() solve in modern JavaScript.
Concept
Understanding jQuery.proxy()
$.proxy() does not call your function immediately. It returns a wrapper function that, when invoked later, calls the original with this forced to the context you specified. The wrapper can be passed to .on(), setTimeout, or any API expecting a callback.
jQuery’s event subsystem recognizes proxied functions: if you pass the original function to .off(), jQuery can still remove the correct proxied handler. When the same function is proxied to different contexts, however, use event namespaces to avoid removing the wrong handler.
💡
Beginner Tip
Before arrow functions existed, $.proxy(obj.handle, obj) was the standard fix for “this is wrong inside my click handler.” Today, obj.handle.bind(obj) or an arrow function property does the same job without jQuery.
Foundation
📝 Syntax
Four signatures from the official jQuery API:
1. Function and context — jQuery.proxy( function, context ) (since 1.4)
jQuery
jQuery.proxy( function, context )
function — the function whose this will be locked.
context — the object that becomes this when the returned function runs.
2. Context and method name — jQuery.proxy( context, name ) (since 1.4)
jQuery
jQuery.proxy( context, "methodName" )
Shorthand for binding context.methodName with this === context.
Returns a new function — the original is not modified.
The proxied function carries jQuery metadata so .off(originalFn) can unbind it.
Cheat Sheet
⚡ Quick Reference
Goal
Code
Lock this to an object
$.proxy(obj.fn, obj)
Bind method by name
$.proxy(obj, "fn")
Pre-fill arguments
$.proxy(fn, ctx, arg1, arg2)
Native replacement
fn.bind(ctx, arg1, arg2)
Safe unbind for proxied fn
.on("click.ns", $.proxy(fn, ctx))
Added / deprecated
1.4 / deprecated 3.3
Compare
📋 jQuery.proxy() vs .bind() vs Arrow Functions
Three ways to control this in callbacks. Pick the one that fits your project’s browser targets and coding style.
$.proxy()
$.proxy(fn, ctx)
jQuery 1.4+ — integrates with jQuery event unbinding; deprecated 3.3
.bind()
fn.bind(ctx)
Native ES5 — standard replacement; works without jQuery
Arrow fn
() => obj.fn()
ES6 — inherits this from enclosing scope; no own this
By name
$.proxy(obj,"m")
jQuery-only shorthand — use obj.m.bind(obj) natively
Hands-On
Examples Gallery
Examples 1–3 follow the official jQuery API documentation. Examples 4–5 cover native .bind() migration and namespace-safe unbinding. Open the Try-it links to experiment in the browser.
📚 Official API Examples
Three demos from api.jquery.com/jQuery.proxy/.
Example 1 — Change Context with function, context
Attach multiple proxied handlers to one button — each locks this to a different object.
jQuery
var me = {
type: "zombie",
test: function( event ) {
var element = event.target;
$( element ).css( "background-color", "red" );
$( "#log" ).append( "Hello " + this.type + " " );
$( "#test" ).off( "click", this.test );
}
};
var you = {
type: "person",
test: function( event ) {
$( "#log" ).append( this.type + " " );
}
};
var youClick = $.proxy( you.test, you );
$( "#test" )
.on( "click", $.proxy( me.test, me ) ) // this === me ("zombie")
.on( "click", youClick ) // this === you ("person")
.on( "click", $.proxy( you.test, me ) ) // this === me (wrong object!)
.on( "click", you.test ); // this === DOM button
One click on #test appends roughly:
"Hello zombie person zombie "
Proxied me.test → this.type is "zombie"
Proxied you.test with you → "person"
Proxied you.test with me → "zombie" (wrong context demo)
Bare you.test → this is the button element
How It Works
Without $.proxy(), passing you.test directly makes this the clicked button. Wrapping with $.proxy(you.test, you) forces this.type to read from the you object every time.
Example 2 — Context and Method Name Signature
Bind obj.test by property name instead of passing the function reference.
Click #test → log shows "John"
this.name works because this === obj
Handler unbinds itself after first click
How It Works
jQuery.proxy(obj, "test") is equivalent to jQuery.proxy(obj.test, obj). The string form is convenient when the method name is known but the function reference is not yet extracted.
Example 3 — Partial Application with Extra Arguments
Pre-bind you and they objects; the event arrives as the last argument.
jQuery
var me = {
type: "dog",
test: function( one, two, event ) {
$( "#log" )
.append( " Hello " + one.type + ": " )
.append( "I am a " + this.type + ", " )
.append( "and they are " + two.type + ". " )
.append( "Thanks for " + event.type + "ing." )
.append( " the " + event.target.type + "." );
}
};
var you = { type: "cat" };
var they = { type: "fish" };
var proxy = $.proxy( me.test, me, you, they );
$( "#test" ).on( "click", proxy );
Click #test → log shows:
" Hello cat: I am a dog, and they are fish. Thanks for clicking. the button."
one = you (cat), this = me (dog), two = they (fish), event = click
How It Works
Arguments after context in $.proxy() are fixed at creation time. When the click fires, jQuery passes the event object after those preset values — same behavior as fn.bind(ctx, you, they).
📈 Modern Patterns
Migration and safe unbinding.
Example 4 — Migrate to Function.prototype.bind()
Replace deprecated $.proxy() with the native ES5 equivalent.
jQuery
var user = {
name: "Alex",
greet: function() {
return "Hi, " + this.name;
}
};
// Legacy jQuery (deprecated 3.3)
$( "#jq" ).on( "click", $.proxy( user.greet, user ) );
// Modern native (preferred)
$( "#native" ).on( "click", user.greet.bind( user ) );
Both buttons log "Hi, Alex"
$.proxy(fn, ctx) and fn.bind(ctx) produce the same this binding
Use .bind() in all new code — no deprecation warning
How It Works
.bind() returns a bound function just like $.proxy(). It is supported in every browser jQuery 3 targets and works in vanilla JavaScript without loading jQuery at all.
Example 5 — Unbind Safely with Event Namespaces
When the same function is proxied to different contexts, use namespaces instead of passing the proxied function to .off().
jQuery
var a = { handle: function() { /* context A */ } };
var b = { handle: function() { /* context B */ } };
// Same function shape, different contexts — jQuery sees one handler id
$( "#btn" )
.on( "click.widgetA", $.proxy( a.handle, a ) )
.on( "click.widgetB", $.proxy( b.handle, b ) );
// Remove only widget A's handler
$( "#btn" ).off( "click.widgetA" );
Before: click runs both [A] and [B]
.off("click.widgetA"): only [B] runs
.off("click.widgetB"): only [A] runs
Namespaces avoid removing the wrong proxied handler
How It Works
jQuery assigns one internal id per function body. Two $.proxy() wrappers around the same function look identical to the event system. Namespaces (click.myPlugin) give you precise control when tearing down individual bindings.
Plugin callbacks — pass proxied methods to setTimeout or AJAX without losing this.
Class-style widgets — bind multiple DOM events to one controller object in a constructor.
Partial application — preset configuration objects before the event argument arrives.
Legacy maintenance — read jQuery UI and older plugins that rely on $.proxy().
Migration audits — replace $.proxy(fn, ctx) with fn.bind(ctx) during jQuery 3.3+ upgrades.
🧠 How jQuery.proxy() Creates a Bound Function
1
Call $.proxy()
You pass the original function, a context object, and optional preset arguments.
Setup
2
Wrapper returned
jQuery returns a new function that stores the original, context, and extra args internally.
Closure
3
Later invocation
When the wrapper runs (click, timer, etc.), jQuery calls the original with this === context.
Execute
4
👉
Args merged
Preset arguments come first; runtime arguments (like the event) are appended. Your method sees the expected this and parameters.
Important
📝 Notes
jQuery.proxy() was added in jQuery 1.4 and deprecated in 3.3. Prefer Function.prototype.bind() in new code.
Additional arguments for partial application were added in jQuery 1.6.
Since jQuery 1.9, null or undefined context preserves the caller’s this (partial apply without rebinding).
jQuery can unbind a proxied handler when you pass the original function to .off().
Proxying the same function to different contexts shares one internal handler id — use event namespaces for safe removal.
Arrow functions (() => obj.method()) lexically capture this and are an alternative when you control the method body.
$.proxy(context, "name") requires name to be a property of context holding a function.
Compatibility
Browser Support
jQuery.proxy() is a jQuery utility available in jQuery 1.4 through 3.x (deprecated 3.3). The recommended native replacement Function.prototype.bind() is ES5 (2009) and supported in all browsers jQuery 3 targets. Arrow functions (ES2015) offer another context fix for methods defined inline.
✓ jQuery 1.4+ · deprecated 3.3
jQuery.proxy()
Works in jQuery 1.x, 2.x, and 3.x. Deprecation warnings appear in jQuery 3.3+ console when used. Native fn.bind(context) is supported in Chrome 7+, Firefox 4+, Safari 5.1+, Edge, IE9+, and Node 0.8+.
95%Via .bind() natively
Google ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll modern versions
Full support
jQuery.proxy()Use .bind()
Bottom line: Safe to read in any jQuery codebase. For new code and jQuery 3.3+ migrations, replace $.proxy(fn, ctx) with fn.bind(ctx). jQuery.proxy(context, 'name') becomes context[name].bind(context).
Wrap Up
Conclusion
jQuery.proxy() solves one of JavaScript’s most common beginner traps: losing your object when passing its methods as callbacks. By returning a wrapper with a fixed this, it made object-oriented event handlers practical in jQuery 1.x-era code.
Modern projects should use Function.prototype.bind() or arrow functions instead. The mental model is identical — practice the official examples above until you can predict what this will be in every handler, then migrate confidently to native APIs.
Store bound functions in variables when attaching and removing handlers
Use event namespaces (click.myApp) for proxied handlers on shared functions
Prefer arrow functions when defining handlers inline in object literals
Pass the original function to .off() when jQuery proxy metadata is present
❌ Don’t
Introduce $.proxy() in greenfield code without reason
Assume this is your object when passing bare method references
Proxy the same function to two contexts and expect precise .off(fn) behavior
Forget that preset proxy args come before the event argument
Confuse $.proxy(obj, "test") with calling obj.test() immediately
Summary
Key Takeaways
Knowledge Unlocked
Six things to remember about jQuery.proxy()
Lock this for callbacks and handlers.
6
Core concepts
📝01
Returns fn
Wrapper, not call.
API
this02
Fixed ctx
Always context.
Core
"m"03
By name
$.proxy(o,"m")
Shorthand
+args04
Partial
Since 1.6.
Apply
.bind05
Native
Preferred.
Modern
.ns06
Namespaces
Safe .off().
Unbind
❓ Frequently Asked Questions
jQuery.proxy(function, context) returns a new function that always runs with this set to context — no matter where it is called from. It solves the classic JavaScript problem where this inside an event handler points to the DOM element instead of your object.
Yes in jQuery 3.x, but deprecated since jQuery 3.3. New code should use the native Function.prototype.bind() method, which does the same job in all modern browsers. jQuery.proxy() remains useful when maintaining older codebases.
Function.prototype.bind() is native ES5 — fn.bind(context) returns a bound function. jQuery.proxy(fn, context) is jQuery's equivalent, added in 1.4. jQuery also accepts jQuery.proxy(context, 'methodName') to bind a method by name. Both support partial application of extra arguments.
When you pass obj.handle to .on('click', obj.handle), this inside handle is the clicked element — not obj. $.proxy(obj.handle, obj) wraps the function so this always refers to obj, letting you access obj properties and call other obj methods.
jQuery tracks proxied functions so .off() can remove them if you pass the original function. However, when the same function is proxied to different contexts, jQuery treats all proxies as one handler. Use unique event namespaces like .on('click.myWidget', $.proxy(fn, ctx)) and .off('click.myWidget') instead.
Since jQuery 1.6, pass additional arguments after context: $.proxy(fn, ctx, arg1, arg2). They are prepended before arguments received at call time (like the event object). Since jQuery 1.9, context null or undefined preserves the caller's this — useful for partial application without changing context.
Did you know?
JavaScript’s Function.prototype.bind() was standardized in ES5 (2009) — five years before jQuery added partial-argument support to $.proxy() in version 1.6. jQuery deprecated $.proxy() in 3.3 because every modern environment already ships native .bind(), making the jQuery wrapper redundant for new development.