Should You Use the ‘var $this = $(this);’ Syntax in jQuery?

The other day I tweeted that I

May succumb to this this syntax: var $this = $(this);*

May succumb to this this syntax
Click image to see original Facebook thread

Because I use Hootsuite and it’s a simple button push, I also posted it to Facebook. George Winters saw it there and wondered what I meant.

I was referring to a common jQuery coding practice.

var $this = $(this);

In the past, my answer on whether this practice was useful or necessary has always been “no”. I tend to use the convention of naming my variables like this:

var thisTermId = $(this).attr("a9");

and I’ve felt that this was enough “this” stuff. (Yes, this post is going to have a lot of this this stuff in it.)

So why do we care?

In this example, I’m parsing out the results form a call to the TaxonomyClientService GetChildTermsInTerm operation. (More on this in a later post.) We get back a text representation of the XML which ends up looking like this after some conversions:

<TermStore>
  <T a9="988b1b74-3b87-4f40-a6ee-066e592fbe89" a21="false" a61="0" a1000="227">
    <LS>
      <TL a32="Cereal" a31="true"/>
      <TL a32="Breakfast Treat" a31="false"/>
      <TL a32="Grains" a31="false"/>
      <TL a32="Bowl of breakfast" a31="false"/>
    </LS>
    <DS/>
    <TMS>
      <TM a24="d8110aa1-d8c2-4e0f-8a99-7e82db8a32dd" a12="Breakfast Foods" a40="" a17="true" a67="" a45="988b1b74-3b87-4f40-a6ee-066e592fbe89"/>
    </TMS>
  </T>
  <T a9="b793fd58-45b7-4540-9098-140815864900" a21="false" a61="0" a1000="291">
    <LS>
      <TL a32="Bacon" a31="true"/>
      <TL a32="Manna" a31="false"/>
      <TL a32="Rackley's Favorite Food" a31="false"/>
    </LS>
    <DS/>
    <TMS>
      <TM a24="d8110aa1-d8c2-4e0f-8a99-7e82db8a32dd" a12="Breakfast Foods" a40="" a17="true" a67="" a45="b793fd58-45b7-4540-9098-140815864900"/>
    </TMS>
  </T>
  ...
</TermStore>

The data is pretty well organized, but I need to get it into an array so that I can use it in my application. To do this, I use jQuery selectors and .each() logic to iterate through the data, much like C# folks use enumerators.

In jQuery, when you use a selector, you can refer to the matches with $(this). Here’s a simplified version of the code I’m using:

$($termsXML).find("T").each(function() {
  var thisTermId = $(this).attr("a9");
  var thisTermName = $(this).find("TL[a31='true']").attr("a32");
  ...
});

In the example, I’m finding all of the elements (terms) in the $termsXML jQuery object and then parsing out two of the attributes inside them. I’m using $(this) in two different places (and in the actual code, many more places). Many JavaScript developers would do this instead:

$($termsXML).find("T").each(function() {
  var $thisTerm = $(this);
  var thisTermId = $thisTerm.attr("a9");
  var thisTermName = $thisTerm.find("TL[a31='true']").attr("a32");
  ...
});

There are a few benefits:

  • $(this) is only evaluated once (minor efficiency)
  • You can use a more descriptive name for $(this). I’m using $thisTerm above because it’s a taxonomy term.
  • By preceding the variable name with the $ sign, you’re reminding yourself that it’s a jQuery variable, not just a plain old JavaScript variable.

This all is really up to you. JSLint and JSHint don’t care whether you do this or not, but your code may be more readable over time. Whatever conventions you decide to follow, the more important thing is that you remain consistent over time. I’ve not used the $this syntax before and if I start doing it selectively in SPServices, for instance, I’ll have a tougher time maintaining it.


* I love playing with words like that. Check out this great picture I saw on Facebook the other day. But I digress…ship-shipping ship

Similar Posts

8 Comments

  1. All good points here. I don’t have a hard rule, but I do use this kind of approach with some consistency.

    Instead of $thisTerm I’d probably just use $term because that’s too much of “this” ;)

    If I’m going to grab say 5 or more values from $(this) I usually do var $term = $(this) and then use $term.attr( ... ) for some micro-optimization. But if I’m just using $(this) a few times I don’t bother.

    1. I warned you about the this stuff!

      I try to apply the “rule if three” fairly consistently. If I’m going to use something which must be evaluated three or more times, I put it into a variable.

      M.

      1. Marc, I would argue that it also depends a lot on what you put behind “evaluation”. Clearly $(this) (just putting a wrapper around an element) is not the same effort as a full DOM crawl, like for example $(“TL[a31=’true’]”).

        1. Christophe:

          Optimization is always a hard thing to generalize because it is so dependent on the specific data and user activity patterns. I intentionally kept the example here pretty simple (but real) to show what the idea was. In actual practice where we’re evaluating a dozen or more attributes there are number of optimization options, including simply getting *all* of the attributes into an array by looping through the element.

          I think the point about consistency is almost more important over the miniscule performance differences in many cases. Readable code is rare in my experience, and if one chooses to use a pattern like this, being consistent is key, as is using clear variable names.

          M.

          p.s. $(“TL[a31=’true’]”) wouldn’t be a full DOM crawl, but just a selection inside an already cropped XML element.

  2. I am not convinced by this kind of micro-optimization. Actually, in your example, if you are really looking for micro-optimization you should be using this.getAttribute(“a9”) as it’ll save you more than everything you save with the variable wrapping.

    Your points 2 and 3 definitely make sense, especially with nested loops where you end up losing track of who “this” is (compare a descriptive name with var that=$(this)…). I also apply a similar logic with promises, for example naming my variable “promisedTasks”.

Leave a Reply to Christophe Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.