Description

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.

Change History

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.

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.

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.

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

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

instead of a

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

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