Side navigation
#7783 closed enhancement (fixed)
Opened December 15, 2010 02:51AM UTC
Closed June 27, 2011 06:19PM UTC
Last modified October 15, 2012 10:00PM UTC
Fixing $.proxy to work like (and use) Function.prototype.bind
| Reported by: | gf3 | Owned by: | gf3 |
|---|---|---|---|
| Priority: | low | Milestone: | 1.6 |
| Component: | core | Version: | 1.4.4 |
| Keywords: | Cc: | ||
| Blocked by: | Blocking: |
Description
As it stands currently, $.proxy is in a weird place. It's likely too advanced of a tool for the average user, and crippled for advanced users. It lacks the ability to partially apply arguments and doesn't take advantage of native implementations where available. As well, $.proxy is being used internally to set matching guids (in $.fn.bind and $.fn.toggle), which is an unnecessary performance hit as well as reliance on an indirect side-effect of $.proxy.
My proposal is to:
- Make $.proxy spec-compatible.
- Use native implementations where available.
- Remove the non-standard object/key syntax (breaking).
Attachments (0)
Change History (16)
Changed December 15, 2010 03:01AM UTC by comment:1
Changed December 15, 2010 05:10PM UTC by comment:2
| component: | unfiled → core |
|---|
I am fully in favour of this landing - partial application is worth it alone, and I agree - the stringy syntax is really not necessary and kinda feels yucky, so I am not averse to losing it. If people have used it in the past year since 1.4 came out, I think we can guide them toward the proper syntax...
What do other people think about this for 1.5?
Changed December 15, 2010 08:09PM UTC by comment:3
I’m not sure what the project’s outlook has been with regards to removing things outright like that in a new version without deprecating it for a release.
(Unrelatedly, I also kind of feel like the method signature should be (thisObj, fn, args…) since that matches other functions that rebind this like Function.call and Function.apply, but that probably won’t happen since it is an even more extreme bc break.)
Changed December 15, 2010 09:08PM UTC by comment:4
| _comment0: | Back when this was in discussion on the jQuery Core google group, I had argued the same points - and ultimately $.proxy was the outcome - so I'm gladly in favor of this change, I also think `(thisObj, fn, args…)` should be used - the function def would have to be nasty overloaded with ugly argument manipulation. → 1292447375989704 |
|---|---|
| owner: | → gf3 |
| status: | new → assigned |
Back when this was in discussion on the jQuery Core google group, I had argued the same points - and ultimately $.proxy was the outcome - so I'm gladly in favor of this change, I also think (thisObj, fn, args…) should be used - however the function def would be nasty overloaded with ugly argument manipulation.
Changed December 15, 2010 11:24PM UTC by comment:5
| _comment0: | Replying to [comment:4 rwaldron]: \ > Back when this was in discussion on the jQuery Core google group, I had argued the same points - and ultimately $.proxy was the outcome - so I'm gladly in favor of this change, I also think `(thisObj, fn, args…)` should be used - however the function def would be nasty overloaded with ugly argument manipulation. \ \ Replying to [comment:3 snover]: \ > (Unrelatedly, I also kind of feel like the method signature should be `(thisObj, fn, args…)` since that matches other functions that rebind `this` like `Function.call` and `Function.apply`, but that probably won’t happen since it is an even more extreme bc break.) \ \ I've followed the style of `$.map` et al, where the instance which would normally be acted upon is the first argument. E.g.: \ \ `ar.map( fn ) → $.map( ar, fn )` \ \ `fn.bind( context ) → $.proxy( fn, context )` \ \ `fn.bind( context, arg1, arg2 ) → $.proxy( fn, context, arg1, arg2 )` \ \ I think if Function#call were implemented in jQuery it would have the following signature: `$.call( fn, context, arg1, argN)`. → 1292455623986724 |
|---|
Replying to [comment:4 rwaldron]:
Back when this was in discussion on the jQuery Core google group, I had argued the same points - and ultimately $.proxy was the outcome - so I'm gladly in favor of this change, I also think (thisObj, fn, args…) should be used - however the function def would be nasty overloaded with ugly argument manipulation.Replying to [comment:3 snover]:
(Unrelatedly, I also kind of feel like the method signature should be(thisObj, fn, args…)since that matches other functions that rebindthislikeFunction.callandFunction.apply, but that probably won’t happen since it is an even more extreme bc break.)
I've followed the style of $.map et al, where the instance which would normally be acted upon is the first argument. E.g.:
ar.forEach( fn ) → $.map( ar, fn )
fn.bind( context ) → $.proxy( fn, context )
fn.bind( context, arg1, arg2 ) → $.proxy( fn, context, arg1, arg2 )
I think if Function#call were implemented in jQuery it would have the following signature: $.call( fn, context, arg1, argN).
Changed December 15, 2010 11:37PM UTC by comment:6
Added a commit to add a quick test to $.support for native bind, as per ajpiano's suggestion:
https://github.com/gf3/jquery/commit/5b1b57850cfd4c92a4f9231581dff7faac489566
Changed December 16, 2010 09:21PM UTC by comment:7
Relevant pull request:
Changed January 01, 2011 11:05PM UTC by comment:8
| milestone: | 1.next |
|---|---|
| priority: | undecided → low |
Changed January 01, 2011 11:07PM UTC by comment:9
| milestone: | → 1.5 |
|---|
Changed January 21, 2011 03:35PM UTC by comment:10
Added the old syntax back in.
Changed April 10, 2011 08:51PM UTC by comment:11
| milestone: | → 1.6 |
|---|---|
| resolution: | → fixed |
| status: | assigned → closed |
Landed.
Changed June 27, 2011 04:58PM UTC by comment:12
| keywords: | → needsdocs |
|---|---|
| milestone: | 1.6 |
| resolution: | fixed |
| status: | closed → reopened |
Changed June 27, 2011 04:59PM UTC by comment:13
note that new docs should cover the latest behaviour after the removal of Function.prototype.bind
https://github.com/jquery/jquery/commit/15da298f72bf94a95563abc12b8e6fec8c604099
Changed June 27, 2011 06:19PM UTC by comment:14
| milestone: | → 1.6 |
|---|---|
| resolution: | → fixed |
| status: | reopened → closed |
It's ok to have closed tickets that need docs, just add keyword needsdocs.
Changed June 27, 2011 06:36PM UTC by comment:15
#9679 is a duplicate of this ticket.
Changed October 15, 2012 10:00PM UTC by comment:16
| keywords: | needsdocs |
|---|
I've committed a fix which takes care of the following:
The bind fallback I used is based on research from the Prototype bug tracker and is ultimately by Juriy Zaytsev (@kangax).
Native bind is used where possible, which is over twice as fast as jQuery's current solution in Chrome 9.
The non-standard object/key syntax has been removed. Yes, this is a breaking change, however it is trivial to use the proper syntax. It adds unnecessary complexity for virtually zero gain.
Internally jQuery was using $.proxy only to set matching guides on related functions. This caused unnecessary overhead. And is just plain wrong. I've fixed this (which I would label as an actual bug).
Patch is on github, a pull-request can be made: https://github.com/gf3/jquery/commit/9f8cd6c499844451468257140e71f611abb3a040