52

I saw some code around the web that uses the following statement

if ($($(this)).hasClass("footer_default")) {
      $('#abc')
        .appendTo($(this))
        .toolbar({position: "fixed"});
    }

What is the use of $($(this)) and why is that necessary here?

keaukraine
  • 5,315
  • 29
  • 54
guest
  • 2,185
  • 3
  • 23
  • 46
  • 3
    Change it to just $(this), It will give the same result – Adil Feb 10 '14 at 07:18
  • 74
    It means some moron figured he'd be safe and wrap it twice. – adeneo Feb 10 '14 at 07:18
  • 14
    It means - "Who let *that* code get committed?" – user2864740 Feb 10 '14 at 07:21
  • I've also done that way one time and figured $(this) was not working but $($(this)) was working. But forget about that. There might be difference. – Bhojendra Rauniyar Feb 10 '14 at 07:23
  • 5
    Also note that it is more efficient to assign `$(this)` to a local variable once instead of doing `$(this)` multiple times. – Alvin Wong Feb 10 '14 at 10:16
  • It also means the guy that wrote this was on a coffee break or something because that's plain pointless! – War Feb 10 '14 at 11:38
  • 9
    It's what we call superstitious code. – Boann Feb 10 '14 at 12:24
  • 1
    This is like asking what the difference between `(5 + 5)` and `((5 + 5))` is. Plus it's been asked before. No more rep cow for you. –  Feb 10 '14 at 15:16
  • @AlvinWong is it really more efficient? I've wondered about that. Certainly if `this` is a string, but if it's already a DOM object? I mean, I'm sure it takes a non-zero amount of time/resources to jQuery-ify a DOM node, but is it significant? – Turner Hayes Feb 10 '14 at 15:55
  • 1
    @adeneo What about `var jquery; while (true) { jquery = $(jquery); }`? – Cole Tobin Feb 10 '14 at 17:02
  • @TurnerHayes - In most cases it's not noticeable, but for complex selectors, it can be quite a bit faster. For `this`, it really makes no difference, as the `this` keyword is interally cached by all modern browsers, and just wrapping a native object in jQuery takes only nanoseconds in newer browsers. In other words, depends on what you're doing! Caching *everything* isn't necessarily a bad idea, but in many cases not neccessary. Should have answered this one, but I figured it would be closed as soon as someone spotted a duplicate, can't believe it got that many upvotes! – adeneo Feb 10 '14 at 17:59
  • I would have added a couple of try-catches wrapping that too, just in case. Quality gate passed ! – Danziger May 21 '17 at 17:22

6 Answers6

78

Yes, $($(this)) is the same as $(this), the jQuery() or $() function is wonderfully idempotent. There is no reason for that particular construction (double wrapping of this), however, something I use as a shortcut for grabbing the first element only from a group, which involves similar double wrapping, is

$($('selector')[0])

Which amounts to, grab every element that matches selector, (which returns a jQuery object), then use [0] to grab the first one on the list (which returns a DOM object), then wrap it in $() again to turn it back into a jQuery object, which this time only contains a single element instead of a collection. It is roughly equivalent to

document.querySelectorAll('selector')[0];, which is pretty much document.querySelector('selector');

chiliNUT
  • 18,989
  • 14
  • 66
  • 106
  • 1
    Thanks. I think this is what I was looking for. I have seen this throughout the web, now I am more aware of cases related to double wrapping. – guest Feb 10 '14 at 07:38
  • 2
    Not exactly idempotence. Idempotent function always return the same if given the same input, so a pure function is naturally idempotent. For instance, square(x) is idempotent, but calling square(square(x)) will return a different result to square(x). In this sense jQuery is rather good at equivocating, rather that idempotence. – Owen Feb 10 '14 at 11:43
  • 3
    Frankly, I find `$($('selector')[0])` significantly harder to read, compared to `$('selector:eq(0)')` or even `$('selector:first')`, and it will perform worse because of the double "constructor". – UweB Feb 10 '14 at 12:25
  • 8
    Owen, I believe you are confusing idempotence with injection. Check [Idempotence](http://en.wikipedia.org/wiki/Idempotence) and [Injection](http://en.wikipedia.org/wiki/Injective_function). Anyway, $() is not generally idempotent, but if the argument is a jquery object it will return the object it received. – Luis Carvalho Feb 10 '14 at 12:29
  • Or, if you can't tweak the selector like @UweB suggests, you could still use `$('selector').eq(0)`. – Ilmari Karonen Feb 10 '14 at 12:30
  • 1
    @Owen, I meant idempotent like, f(x)=f(f(x)), and now that you mention it, I believe the SO I am linking to has comments engaging in the same discussion of which definition is "correct," so I suppose it might be more accurate to say that $() is mathematically idempotent? – chiliNUT Feb 10 '14 at 13:01
  • 3
    I personally prefer `$('selector').eq(0)` if I'm trying to retrieve only the first element as a jquery object – George Feb 10 '14 at 15:54
  • To get the first element in a jquery collection you can also just use $('selector').get(0) – Alexander Kludt Feb 10 '14 at 16:44
  • I tend to use `$('selector:nth(0)')` for that - less to remember for more flexibility, since `:nth()` can go anywhere in the selector – Izkata Feb 10 '14 at 17:07
  • 1
    @LuisCarvalho, if the argument is a jquery object, then it will return the object it recieved. and since any input will always output a jquery object (http://stackoverflow.com/questions/1302428/what-does-jquery-actually-return), then it is generally idempotent. – chiliNUT Feb 11 '14 at 02:43
29

You can wrap $ as many times as you want, it won't change anything.

If foo is a DOM element, $(foo) will return the corresponding jQuery object.

If foo is a jQuery object, $(foo) will return the same object.

That's why $($(this)) will return exactly the same as $(this).

sdabet
  • 18,360
  • 11
  • 89
  • 158
8

There is no specific need for double-wrapping and $($(this)) is exactly the same as $(this).

That said, I once found this double-wrapping in one file in my project, committed by another developer. Tracking the changes through revision, turned out that it started as $($(this).find('selector').first()) - that is, the result of some selector was wrapped to create a new object. Then for whatever reasons, the selector was removed and only the double-wrapping of this remained. Needless to say, on the next commit it was changed to $(this).

Aleks G
  • 56,435
  • 29
  • 168
  • 265
6

As explained before me, $($(this)) and $(this) are absolutely identical. jQuery returns the same jQuery object if you try to wrap it more than once.

Additionally, for performance considerations it is a good practice to reuse jQuery objects - it is quite expensive to create jQuery objects, especially the ones with complex selectors. Example:

var $this = $(this);
if ($this.hasClass("footer_default")) {
    $('#abc')
        .appendTo($this)
        .toolbar({position: "fixed"});
}

Just google for 'jQuery best practices' - it will take a 30 min for you to learn these basics and you will use jQuery way more effectively.

keaukraine
  • 5,315
  • 29
  • 54
3

There is no meainig of doing that.

The following code return the same:

console.log($($(this)).hasClass("footer_default"))
console.log($(this).hasClass("footer_default"))

a boolean value depenging on if the selected element has or not the class footer_default:

.hasClass( className )Returns: Boolean

Demo: http://jsfiddle.net/IrvinDominin/aSzFn/

Irvin Dominin
  • 30,819
  • 9
  • 77
  • 111
3

$(this) and $($(this)) both return jquery object.

There is no difference between these two.

Hasib Tarafder
  • 5,773
  • 3
  • 30
  • 44