29

In 2009, ECMAScript 5 added a built-in bind() function which takes an object as a parameter and returns an identical function in which this will always refer to the object you passed it. (I couldn't find anything that looked like a canonical documentation link.)

How is this different from jQuery's $.proxy() function? Did $.proxy() come first before ECMAScript 5 was released? Is there a particular reason to favor $.proxy(function(){}, this) over function(){}.bind(this)?

stedman
  • 385
  • 4
  • 5
Max Cantor
  • 7,949
  • 6
  • 42
  • 59

5 Answers5

36

proxy came first and you should likely favor bind as it is a standard. The way they are called varies slightly (due to being attached to Function.prototype vs just being a function) but their behavior is the same.

There is a pretty good post here: jQuery.proxy() usage, that ends with that advice.

Community
  • 1
  • 1
Matt Whipple
  • 6,803
  • 1
  • 21
  • 34
9

Edit

Please pay no attention to this post (despite being the accepted answer).
Long story short, it was my own fault for making assumptions about the context of the question, rather than just looking up the API docs, and was accepted as the answer before I could realize my own stupidity (making assumptions, without validating them) and delete it.

Matt Whipple's answer is 100% correct, and while I disagree with his statement that real Proxies are useless in JS (they would be fantastic in some low-level concerns), the rest of his statements are flat-out objectively correct (aside from actual dates for .bind vs .proxy, as .bind was in the spec years before it landed consistently in browsers).

Below is my shame, in the stocks for all to see...

Feel free to throw tomatoes at it.
If you want to know why I answered the way I did, read the comments below.


The difference between $({}).proxy() and func.bind({}) is that proxy is a loose connection. You can detach at any time.

That's sort of what proxies are for. The invisible-interface between what you want to do and the thing that will actually do it.

For the record, there's also a $.bind() which is not a proxy. That is to say, it fully binds to this, in the same way that func.bind() does, rather than implementing a mediator-system to attach and detach context from functions at-will.

Norguard
  • 24,349
  • 4
  • 38
  • 45
  • 3
    Both of these functions are higher order functions returning functions that enforce consistent context. The idea of creating a "proxy" in some other form would just be wasteful in JS. The only bind that has been in jQuery has been the familiar `$.fn.bind` which is used to attach event listeners. – Matt Whipple Sep 21 '12 at 02:45
  • I'm not sure I understand what you mean by "loose connection". Could you clarify what you mean? – Jo Liss May 12 '15 at 14:12
  • 1
    @JoLiss I'd love to. Sadly, this answer was one of the black-marks on my record, and was poorly answered, based on a) assumptions I had made about its place in the jQuery API (based on what I'd read of the source, rather than conferring with the API documentation) because of b) a mental lapse in the purpose of jQuery's `$.bind( )`, compared with `Function.prototype.bind( )`. I hadn't been able to delete it, as it magically got accepted as the answer, faster than I could realize how dumb my assumptions were. Perhaps I will attempt to edit it, now that you've brought it back to my attention. – Norguard May 19 '15 at 16:52
  • @JoLiss For the record, my head, at the time I was writing this, my brain was busy lost in the system of invisibly managing listener registration and withdrawal, on elements, hidden behind the curtains of the `$.bind( )` (and similar jQuery static / instance methods). That was the proxy I was referring to, as it *is* actually responsible for acting as a proxy for dynamic dispatch, and is a more interesting problem to solve (given that until now, JS didn't have an elegant solution for actual proxies; polymorphism in spades, but not a proxy). ***PS***: thank you for Broccoli – Norguard May 19 '15 at 17:01
  • The statement that proxies would be wasteful in JS was a little extreme. They would definitely be useful in _some_ cases. Some proxy derived/related patterns like Decorator can be more simply handled through mixins and first class functions in JS and that was extrapolated to my perception of the question. Basically they're a good fit when a proxy is what you want, but shouldn't be used blindly because they were the only option in language X – Matt Whipple Jun 26 '15 at 16:24
  • 1
    ROFLMFAO this is the most hilarious ANSWER i HAVE EVER SEEN ON sso – Tilak Maddy Apr 21 '17 at 08:03
8

$.proxy came first. Below is a simple way to preserve a particular context on function call

var myProxy = (function(context,fn){
  return function(){
      fn.call(context);
  }
})( myContext, myFn );

You could easily use this before it came out jquery.

Answer is simple: bind is the official. Use bind - if it really is supported in browsers which is required to run the script

abuduba
  • 4,716
  • 7
  • 24
  • 40
6

From Underscore bind vs jQuery.proxy vs Native bind

In addition to what is already mentioned, there's another difference between $.proxy() and .bind. Methods bound with $.proxy will return the same reference if called multiple times; jQuery caches functions proxied to an Object.

jsFiddle

Community
  • 1
  • 1
Benny Bottema
  • 9,605
  • 10
  • 59
  • 80
1

Here is a test you could try to for performance comparison.

http://jsperf.com/bind-vs-jquery-proxy/5

At this time, October 2014. The performance varies like crazy between browsers. IE 11 native bind is fastest.

However, for all three browsers I tested with, native bind out preform jquery proxy. And since bind() is standard, I would suggest sticking to it if possible.

Morio
  • 6,142
  • 3
  • 20
  • 26