2

I'm curious from both a performance and a "best practices" standpoint. I'm using a lot of jQuery in my JavaScript, and often find myself passing jQuery objects as arguments into functions I'm writing. Is it more efficient/effective to pass the selector string rather than the actual jQuery object as the argument? Is this just a stylistic difference, or are there any good reasons to use one method over the other?

Using jQuery objects in arguments:

function updateSelectOptions(optionsData, $selectElement) {

    // function code

}

Or using a selector string as the argument:

function updateSelectOptions(optionsData, selectorString) {

    var $selectElement = $(selectorString);
    // function code

}
Josh KG
  • 5,050
  • 3
  • 20
  • 24
  • jQuery doesn't do caching of selector results as far as I'm aware, so I'd advise against it. It also doesn't provide flexibility to allow you to pass elements not added to the DOM yet. – Qantas 94 Heavy Dec 03 '14 at 00:25
  • 3
    Javascript passes objects by reference (not really, call by sharing, but close enough). Passing the reference means I don't have to re-enter jquery to locate the element and build an object as you would have to do if you passed the selector. The first will be much faster. – Chris Caviness Dec 03 '14 at 00:37

4 Answers4

4

You should accept anything the jQuery constructor can for maximum flexibility.

Re-wrapping a jQuery collection doesn't blow up, so I often use something like...

var fn = function(elems) {
    var $elems = $(elems);
};

That way, you can accept a jQuery collection, selector string or reference to native DOM element(s).

alex
  • 479,566
  • 201
  • 878
  • 984
  • 1
    While maximizing flexibility, it looks like this would actually create a clone if you pass a jQuery object into this function: http://api.jquery.com/jquery/#cloning-jquery-objects (incurring a bit of performance hit) – Josh KG Dec 03 '14 at 00:57
  • @JoshKG Perhaps, but if you've found it to be the bottleneck of your application, I'd be surprised. – alex Dec 03 '14 at 01:51
3

If you find yourself wanting to write a function that takes a jQuery object as a parameter, why not just make your function a jQuery plugin? It's pretty easy, and it makes using the function fit in with the rest of your jQuery code.

Instead of

function something(jq) {
   jq.css("color", "red");
});

you'd write

$.fn.something = function something() {
  this.each(function() {
    $(this).css("color", "red");
  });
  return this;
};

Now when you want to turn something red, you can just say

$(".whatever").something();

The value of this in a jQuery plugin is the jQuery object that's being passed along the chain. You don't have to wrap it with $(this). Unless your function is something that returns some value, it's good to return whatever's passed in so that you can use your own plugin in the middle of a dotted chain.

Pointy
  • 405,095
  • 59
  • 585
  • 614
1

In my opinion, passing the object is fine and would be better for performance.

Why?

Most of the time, the reason for using functions is to reuse code. Hence, if you pass the string (the selector) such as updateSelectOptions(optionsData, selectorString) every time you call the function and then use that string to select the element:

var $selectElement = $(selectorString);

This will consume more memory, because the element will have to be searched for every function call.

Where if you pass the cached object this element will only be selected and searched for only once.

Sam Battat
  • 5,725
  • 1
  • 20
  • 29
0

The second approach remove any reference to the object after the function finished to execute. The first one allow you to keep the reference to the object to manipulate it outside the scope of the function.

Verhaeren
  • 1,661
  • 9
  • 10