12

I had to jump into jQuery development without getting too much time into learning all the associated basics, so there is one thing that throws me off quite a bit.

I see two different ways our developers access jQuery objects:

Case 1:

var container =  $("#containerId");

// Then use it as:
container.hide();

Case 2:

var container =  $("#containerId");

// Then use it as:
$(container).hide();

From my thin up to date knowledge, by wrapping a container as in var obj = $(container), we get a jQuery object obj that we can further work with.

But then why do I see intermittently developers wrapping it again when using as in $(obj).doSomething()?

Edit: the question suggested as duplicate is asking about best practices and although similar, my question is purely on understanding of jQuery object wrapping.

eYe
  • 1,695
  • 2
  • 29
  • 54
  • 11
    Case two is redundant – MysterX Feb 08 '16 at 15:42
  • 8
    You see that because either (a) they are unsure at that point in the code if it is a jQuery object or a selector (sometimes for example a function argument may be unknown whether it's a jQuery object or a selector), or (b) because they don't know any better. – random_user_name Feb 08 '16 at 15:42
  • 5
    Perhaps they're mistaking `obj` for a dom object, and not a jquery one? It's generally considered good practice to prefix jquery objects with a dollar to indicate that they are indeed jquery objects – billyonecan Feb 08 '16 at 15:42
  • As said @MysterX is redundant, and most developers make that because they don't identify the jQuerized objects. Affortunately, jQuery knows that and when it receives a jquery object it ignores the re-declaration – Marcos Pérez Gude Feb 08 '16 at 15:43
  • 4
    Probably more than one dev had their hands in the code - and one of them made a syntax error. Case 2 is redundant. Typiclly when someone wants to make (and denote) a DOM node as a jQuery object you would see something like this: `var $foo = $(".foo");` That way, when someone comes along later to update the code, they can immediately tell that $foo is a jQuery object and not a variable or something else. – Korgrue Feb 08 '16 at 15:48

5 Answers5

8

Second wrapping does nothing as I remember. So if there can be a selector a dom element or a jQuery object you can just wrap it and do not care about what it was.

But if you know it is a jquery object, you shouldn't use wrapping.

doydoy44
  • 5,720
  • 4
  • 29
  • 45
Qwertiy
  • 19,681
  • 15
  • 61
  • 128
  • 1
    None of the answers with code in them will catch all cases where people rightfully or wrongly wrap existing jQuery objects. This is the best answer to OP question. The *"why"* part of question is often a mystery that will never be known – charlietfl Feb 08 '16 at 15:58
3

When developers develop a function, for example in a jQuery plugin, that can get a parameter that is either a DOM element or a jQuery object or a selector, then they use it:

function x(container) {
    container = $(container);
    // use container as a jquery object
}

// these both work:
x("#containerId");
x($("#containerId"));
x(document.getElementById("containerId"));
Gavriel
  • 18,880
  • 12
  • 68
  • 105
2

Case 1: Using a jQuery selector to find a dom element and return a jQuery object:

var container =  $("#containerId");

// Then use it as:
container.hide();

Case 2: Redundant/mistake (or perhaps if you're unsure if a variable is already a jQuery object but you need it to be): Using a jQuery selector to find a dom element and return a jQuery object then pass it to a new jQuery object:

var container =  $("#containerId");

// Then use it as:
$(container).hide();

Case 3: Select a dom element then use it in constructor for a new jQuery object (on which you then call hide() )

var container =  document.getElementById("#containerId");

// Then use it as:
$(container).hide();
Moob
  • 14,420
  • 1
  • 34
  • 47
0

Short answer: Case 2 creates a jQuery object from an existing jQuery object, which is unnecessary.

$ is an alias for the jQuery Selector function. The function can take a few different arguments, such as...

  1. A string: var container = $("#containerId");
  2. An html element: var document = $(document);
  3. A jQuery element: var container = $($("#containerId"))

In the 3rd example, the 2nd call to the Selector function works, but it unnessesary.

Josh Noe
  • 2,664
  • 2
  • 35
  • 37
0

Case 1 is always preferred. Always cache and reuse jQuery objects if possible. This will give the best performance.

Case 2 is the easiest way to ensure you're working with a jQuery object. There are better ways, which you can see in this SO post. I would never recommend selecting objects like this. If I was expecting a jQuery object, I would do this instead. e.g.

function hideContainer(container)
{
    if(!(container instanceof jQuery))
    {
         container =  $("#containerId");
    }

    container.hide();
}

It's actually faster to select the object again via the selector string (instead of using the object reference), since it doesn't have to access object properties to determine the selector.

Take a look at these jsPerf test cases and you will see that Case 2 is much slower than Case 1 (it was 40% slower in my case, on Chrome).

But again, I think Case 2 is just the easiest, quickest way to ensure you have a jQuery object; which is why you see it so often.

Community
  • 1
  • 1
Kevin
  • 2,752
  • 1
  • 24
  • 46