Skip to main content

Bug Tracker

Side navigation

#8634 closed feature (wontfix)

Opened March 25, 2011 03:20AM UTC

Closed March 30, 2011 04:24PM UTC

Last modified March 14, 2012 04:32PM UTC

Genericize members of jQuery.fn

Reported by: mjijackson@gmail.com Owned by:
Priority: undecided Milestone: 1.next
Component: unfiled Version: git
Keywords: Cc:
Blocked by: Blocking:
Description

This ticket is the result of a pull request here:

https://github.com/jquery/jquery/pull/285

Basically, the pull request makes a few small changes that allow jQuery.fn.bind, jQuery.fn.one, and jQuery.fn.unbind to operate in the context of any array-like object and does not require that object necessarily be a jQuery object. The idea is that, since jQuery.event knows how to add/remove events from plain objects, it might be exploited for use on plain JavaScript objects.

By making the prototype more generic, this allows subclasses of jQuery.fn to use bind/one/unbind to potentially any object, including themselves. It's just a first step, but the entire prototype could potentially be made generic enough enable using it in the context of any array-like object. If every member of jQuery.fn assumes only that it is being called within the context of an array-like object, instead of an instance of jQuery.fn, it could be much more useful to third parties who wish to extend jQuery.fn or use its members to enhance their own behavior.

Attachments (0)
Change History (6)

Changed March 25, 2011 04:01AM UTC by timmywil comment:1

First of all, I want to be able to utilize the advantage of the prototype from within jQuery core. Second, I don't see this being implemented without significantly damaging the maintainability and security of the jQuery prototype. What array-like objects are you thinking of? Why not use jQuery objects? I don't see the advantage yet. If the items in these arrays aren't what jQuery expects, there's going to problems, so you might as well just keep everything encapsulated in the instances. Perhaps you could provide some use cases to justify the generic approach, because implementing this idea would require an incredible amount of effort.

Changed March 26, 2011 08:30PM UTC by mjijackson@gmail.com comment:2

Replying to [comment:1 timmywil]:

First of all, I want to be able to utilize the advantage of the prototype from within jQuery core.

This ticket isn't so much about making the entire prototype generic as it is about making the implementation of jQuery.fn.bind, jQuery.fn.one, and jQuery.fn.unbind generic. jQuery.event can be safely used with plain JavaScript objects, so it would be nice if the prototype methods that delegate to jQuery.event do so as well.

Second, I don't see this being implemented without significantly damaging the maintainability and security of the jQuery prototype.

I wish you would expound upon exactly what "damaging" effects on maintainability and security you expect it to have, instead of making such a sweeping statement without any support whatsoever.

What array-like objects are you thinking of? Why not use jQuery objects? I don't see the advantage yet.

Basically anything that could be passed to jQuery.makeArray. That's the reason it exists, right? Because there are so many array-like objects in JavaScript. Arrays, objects with integer keys and a length property, arguments, node lists, etc.

If the items in these arrays aren't what jQuery expects, there's going to problems, so you might as well just keep everything encapsulated in the instances.

The only reason for making these methods more generic is for library authors who wish to reuse portions of the jQuery prototype for some purpose. This isn't the general use case.

Perhaps you could provide some use cases to justify the generic approach, because implementing this idea would require an incredible amount of effort.

I disagree that it would be an incredible amount of effort. In fact, I've already done the work in the pull request and it required changing 4 lines of code.

Of course, it's not a big deal. Plain arrays can be run through the jQuery constructor right now to wrap themselves with the jQuery prototype. It's just a matter of convenience and code reuse.

Changed March 26, 2011 08:46PM UTC by timmywil comment:3

_comment0: Ugh, so you're one of those. I've already explained twice why this is damaging to maintainability and security. As I said before in the pull request,, how would you know when the context does or does not have access to the jquery prototype? You either need to assume always, or never, to have it be maintainable and secure. Again, please provide a use case where the existing architecture is not adequate. I haven't seen that yet. Avoiding referencing the prototype does not seem like the proper solution to supporting plain objects. We already do that in other ways in other functions without an inconsistent context. And sometimes, we don't want to support plain objects, so please be more specific. 1301183936650199
_comment1: I've already explained twice why this is damaging to maintainability and security. As I said before in the pull request,, how would you know when the context does or does not have access to the jquery prototype? You either need to assume always, or never, to have it be maintainable and secure. Again, please provide a use case where the existing architecture is not adequate. I haven't seen that yet. Avoiding referencing the prototype does not seem like the proper solution to supporting plain objects. We already do that in other ways in other functions without an inconsistent context. And sometimes, we don't want to support plain objects, so please be more specific. 1301184397924082

I think this hurts maintainability and security because how would you know when the context does or does not have access to the jquery prototype? You either need to assume always, or never, to have it be consistent. I am having trouble thinking of a use case where the existing architecture is not adequate. Perhaps you could provide a code example.

Changed March 26, 2011 11:34PM UTC by timmywil comment:4

_comment0: Ok, I apologize for being an ass. It is a pet-pieve of mine to see that line-for-line analysis of a post. To me, that just says that the person wants to argue and is not willing to see an ounce of validity in your points. I think we can have a more reasonable and level-headed discussion. So, let's start over. If you can explain to me why you think this is needed (even if you feel it is self-evident), I am willing to change my mind and admit it is a good idea. I think it would be very helpful to see some code where this enhancement would get used.1301182480977632
_comment1: Ok, I apologize for being an ass. It is a pet-pieve of mine to see that line-for-line analysis of a post. To me, that just says that you want to argue and is not willing to see an ounce of validity in your points. I think we can have a more reasonable and level-headed discussion. So, let's start over. If you can explain to me why you think this is needed (even if you feel it is self-evident), I am willing to change my mind and admit it is a good idea. I think it would be very helpful to see some code where this enhancement would get used.1301182498592399
_comment2: Ok, I apologize for being an ass. It is a pet-pieve of mine to see that line-for-line analysis of a post. To me, that just says that you want to argue and are not willing to see an ounce of validity in my points. I think we can have a more reasonable and level-headed discussion. So, let's start over. If you can explain to me why you think this is needed (even if you feel it is self-evident), I am willing to change my mind and admit it is a good idea. I think it would be very helpful to see some code where this enhancement would get used.1301184104704850
_comment3: Ok, I apologize for being an ass. It is a pet-pieve of mine to see that line-for-line analysis of a post. To me, that just says that you want to argue and are not willing to see an ounce of validity in my points. I think we can have a more reasonable and level-headed discussion. So, let's start over. If you can explain to me why you think this is needed (even if you feel it is self-evident), I am willing to change my mind and admit it is a good idea. I think it would be very helpful to see some code where this enhancement would get used. Let me apologize again, as I've been informed that I am the one who sounds agitated. This is entirely possible as I haven't had a cigarette in 3 days and am irritable.1301184282219959
_comment4: → 1301184466686909
_comment5: Edited my comments for future usefulness.1301192256335633

Edited my comments for future usefulness. Deepest apologies to mji and all who read the previous.

Changed March 30, 2011 04:24PM UTC by dmethvin comment:5

resolution: → wontfix
status: newclosed

We just don't see a good use for this, so we're closing it.

Changed March 30, 2011 06:09PM UTC by mjijackson@gmail.com comment:6

Sorry for being slow to respond on this ticket, but I just wanted to provide a concrete example of what I'm talking about. This weekend I worked up a piece of code that I call jView. It's essentially a subclass of jQuery.fn that is a wrapper for one element. The goal is to provide a base class for building view hierarchies in JavaScript, similar to the way they are built in desktop frameworks such as Cocoa.

My personal use case for the pull request mentioned at the top of this ticket is demonstrated by this line (and this one and this one).

The purpose for "hijacking" jQuery.fn[bind,one,unbind,trigger,triggerHandler] is to allow these functions to be used to attach events not only to the elements that the view objects wrap but to the view objects themselves. Thus, when one of those functions is called I first check to see if the user has specified an event type with the given name on the prototype. If they have, I bind/unbind the event from the view object itself instead of from the DOM element. jQuery's events subsystem is ideal for this kind of use because it can be used with plain objects as well as elements.

In these cases it would be nice to be able to do a simple

#!js
jQuery.fn.bind.apply([this], arguments)

instead of a

#!js
jQuery.fn.bind.apply(jQuery([this]), arguments)

for example. The extra wrap in a jQuery object shouldn't really be necessary.