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 rebindthis
likeFunction.call
andFunction.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