When jQuery fires a callback function, whether it is an event handler, an each iterator, or a filter function, it will normally give you a DOM element as the function’s context, accessible via the this keyword. It’s common practice to subsequently wrap this in jQuery(...) resulting in a newly constructed jQuery instance.

This is no fault of jQuery’s but this practice of redundant “wrapping” generally sucks.

I “tweeted” a while ago, complaining of this:

Constructing a new jq obj on each iteration just to access some text seems wrong. jQuery(‘a’).map(function(){ return $(this).text(); });

Paul Irish suggested that I use jQuery.text instead of jQuery.fn.text, meaning that I wouldn’t have to bother with constructing a new jQuery object every single time my function was called. This was a good suggestion but unfortunately not all of jQuery’s methods have corresponding single-node functions, and it would mean not being able to chain methods.

This is a growing problem, and is only worsened by developers’ insistence on constructing multiple jQuery objects with the same element! –

jQuery('a').click(function(){
 
    if (jQuery(this).attr('href') === 'blah') {
        jQuery(this).next('.whatever').slideToggle();
    }
 
    jQuery(this).fadeTo('slow', 0.4);
 
    return false;
 
});

Eew! Not only are there multiple pointless constructors, but Mr. Uber Cool jQuery Developer isn’t accustomed to the DOM, so has absolutely no idea that, in most situations, this.href would suffice for getting the href property value. This kind of misuse has been discussed in step #3 here: http://encosia.com/2010/03/30/5-steps-toward-jquery-mastery/.

The real problem remains that there are three jQuery objects being constructed, — I feel that it is a library’s obligation to protect against misuse like this. Even if you’re only constructing one jQuery object in a callback it’s still somewhat pointless, in that you’re only doing so to call a couple of methods…

In light of my concerns I thought it would make sense to experiment with some ways to alleviate this troublesome situation. In the end, I landed on something so dead-simple that I feel silly even shining a spotlight on it:

jQuery.single=function(a){return function(b){a[0]=b;return a}}(jQuery([1]));

76 characters. Here’s the readable version:

jQuery.single = (function(o){
 
    var collection = jQuery([1]); // Fill with 1 item, to make sure length === 1
 
    return function(element) {
 
        // Give collection the element:
        collection[0] = element;
 
        // Return the collection:
        return collection;
 
    };
 
}());

A single jQuery object is being created and is then used for every single call to jQuery.single — so only one jQuery object is ever being created. If you think about it, we tend to wrap elements in jQuery(...) (i.e. in a jQuery instance) so that we can have access to jQuery’s methods. Very rarely do we mutate the object itself — even when you call parent() or children(), the jQuery object itself isn’t being changed — a new object is being returned. It’s this non-mutability which makes this solution viable.

Obviously, you can’t use it in exactly the same was as jQuery(); jQuery.single will only work when you pass a single DOM element. Here’s an example of its usage:

jQuery('a').click(function(){
 
    var html = jQuery.single(this).next().html(); // Method chaining works!
 
    alert(html);
 
    // etc. etc.
 
});

Also, you can’t cache it and save it for later as you normally would… well, actually, you can — but the object will change when you next call jQuery.single, so be careful! And please note that this is only meant to be used in situations where you have a DOM element that requires immediate wrapping.

You might be thinking that we could do away with this trickery by simply remembering to “cache” our jQuery objects, like so (using the example from before):

jQuery('a').click(function(){
 
    var me = jQuery(this);
 
    if (me.attr('href') === 'blah') {
        me.next('.whatever').slideToggle();
    }
 
    me.fadeTo('slow', 0.4);
 
    return false;
 
});

This is a good practice, but is still not quite as speedy as jQuery.single. I absolutely recommend making up your own mind by carrying out your own tests, but having tested jQuery.single() myself I can tell you that it performs better.

You can make it even faster by assigning jQuery.single to a (closely-scoped) variable:

var $_ = jQuery.single;
 
// Use $_(this) ...

Thanks for reading! Please share your thoughts with me on Twitter. Have a great day!