jQuery’s this: demystified

More often that not, in my early dabbling with jQuery and more advanced JavaScript, I found I would constantly get confused over the meaning of “this” in jQuery and my own new libraries.

Hopefully this quick guide can help clarify those confusing moments, because once you’ve got it, it’s simple as pie.

What is “this”?

In many object-oriented programming languages, this (or self) is a keyword which can be used in instance methods to refer to the object on which the currently executing method has been invoked.

Source: http://en.wikipedia.org/wiki/This_(computer_science)

jQuery’s this

There are really two main contexts of ‘this’ in jQuery. The first refers to a to a DOM element, and the second to a jQuery object.

Example of this as a DOM element

‘this’ is a DOM element when you are inside of a callback function (in the context of jQuery), for example, being called by the click, each, bind, etc. methods.

The following code searches for anchor links with the class of ‘newTarget’ and sets the ‘target’ attribute to ‘_new’ (which is a trick to create strict XHTML while still having some links open in a new window).

In this example we are also going to perform a double check to ensure links to the same domain don’t open in a new window using the this object.

$('a.newTarget').each(function() { // <- our anonymous callback
  // check the DOM attribute 'host' on this
  if (this.host != window.location.host) {
    // create a jQuery object using the current DOM element
    $(this).attr('target', '_new');
  }
});

Example of this as a jQuery object

'this' is a jQuery object when you are inside your own jQuery functions. Note that the result of a selector query (i.e. $('a') ) is a jQuery object, which is an array of the matched DOM elements (imagine jQuery is an array with bells on).

jQuery.fn.newTarget = function() {
  // 'this' is a jQuery object at this point - with all the jQuery functions

  return this.each(function() { // return so we don't break the chain
    // now we are inside of a jQuery function, the DOM element is the context
    // so 'this' has changed to become a DOM element.

    if (this.host != window.location.host) {
      $(this).attr('target', '_new');
    }
  });
};

Finishing up

This is far from comprehensive, but equally there's very little to the logic. So long as you remember the context of 'this' changes when moving in and out of object methods then you're on your way.

If you're still not sure, get your hands on Firebug and add 'console.log(this)' within your code to interrogate and understand what 'this' is at that point in your code.

If this still doesn't make sense or I've got it terribly wrong - or you're suddenly enlightened, please do let me know - and I'll do my best to help.

52 Responses to “jQuery’s this: demystified”

  1. The console.log(this) made my day. I was looking for something like that and took me hours.

    I wanted to set a readonly attribute in an input array created dynamically.

    HTML

    <input type="text" id="topics[]" name="topics[]" placeholder="Write some topic" onkeypress="insertTopic(event, this.value, this)" />

    JS (short version)

    insertTopic = function(e, topic, input){
       $(input).attr("readonly", "readonly");
    }

    And that’s it! now it works…

    Thanks a lot!

  2. Crazy helpful, thanks. I’m a relative newb trying to *mix* found code, a combination of regular js and jquery. One of the code examples I wanted to repurpose was littered with “this’s” but was written with jQuery to perform its action on .hover. The regular JS I was inserting into already had its start condition in place where it wrote to the dom with a .innerHtml. I was trying to figure out “how do I remove this .hover conditional and insert this action in place of the innerHtml manipulation.

    My dilemma was “how do I just DO THIS ACTION in this js without requiring a .hover user interaction.
    The breakthrough from your code was actually with “.each.” Boom. Replaced .hover with .each, pasted it into place, and it worked.

    Probably not the smartest way to accomplish it, but it worked. I’m just saying thanks.

Leave a Reply
Not required

CODE: Please escape code and wrap in <pre><code>, doing so will automatically syntax highlight