Reputation: 1320
I believe they both allow you to control the value of 'this', but beyond that, I'm a little unclear and Google/SO isn't helping much so far. Any clarification appreciated. I did find this, but I'm skeptical that it tells the whole story:
"When I first learned about jQuery's proxy() method, I thought it was a little silly; after all, Javascript already has call() and apply() methods for changing execution context. But, once you realize that jQuery's proxy() method allows you to easily bind() and unbind() event handlers regardless of context, it becomes obvious just how powerful this method is.
Upvotes: 9
Views: 3972
Reputation: 32598
call/apply are a single-shot invocation. $.proxy creates a new function permanently bound to something:
fn.call(foo); //call once
var otherFn = $.proxy(fn, foo); // you can call it again later
var otherOtherFn = fn.bind(foo); // ES5 standard way
As a simplification (very simplified), $.proxy
is creating a new function that calls call
:
$.proxy = function(fn, newThis) {
return function() {
fn.call(newThis);
}
}
It is analogous to ES5's Function.prototype.bind
Upvotes: 12
Reputation: 298206
Take a look at the jQuery source:
proxy: function( fn, context ) {
var tmp, args, proxy;
if ( typeof context === "string" ) {
tmp = fn[ context ];
context = fn;
fn = tmp;
}
// Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
if ( !jQuery.isFunction( fn ) ) {
return undefined;
}
// Simulated bind
args = core_slice.call( arguments, 2 );
proxy = function() {
return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
};
// Set the guid of unique handler to the same of original handler, so it can be removed
proxy.guid = fn.guid = fn.guid || jQuery.guid++;
return proxy;
},
If you remove the caching code and make it a little shorter, you essentially get .apply()
(I think I translated the slicing code correctly):
proxy: function(fn, context) {
var args = [].slice.call(arguments, 2);
return function() {
return fn.apply(context || this, args.concat([].slice.call(arguments)));
};
}
Upvotes: 6
Reputation: 1244
$.proxy
you can call on a function and the function it returns will ALWAYS have a particular context. That means that if you ran
$.proxy(function() {console.log(this.val)}, {val: 1}).call({val: 2});
It would log 1
because the function is always bound to the object that was initially passed to proxy
Upvotes: 1