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.
You should follow me on Twitter here I'll tweet about JavaScript, HTML 5 and other such gems (amongst usual tweet-splurges)


Thanks for $(this)!
Great article. I have a persistent problem that maybe you can help with. How do you call Jquery from with a custom Javascript object and reference the object from within the Jquery callback function?
Example:
How do you pass a reference to the customClass since "this" is replaced by Jquery? I haven't found an answer yet. I haven't even been able to find a single example of code where someone tried to call Jquery from with a custom Javascript object. Am I going about this all wrong?
@Tyson - your code is fine. The solution is just to cache a copy within your function call.
e.g.
Thanks for the code example! You just saved me hours of pain trying to figure out how to use jquery inside of a custom object method.
I quickly read thru your article and I gained a very valuable lesson. I did not know 'this' could change contexts like that. You write very articulately and precise. Thanks a bunch. I wish you the best at whatever u r pursuing.
great article
i have got a problem
$('.delete').click(function(){
$.post("test2.php",{id:txt},function(){
this...somecode});});
if i want to refer "this" to the element $('.delete'), what shall i do?
@Jian - you need to cache the element within the click function. e.g.
I tried this but it did not work
$('.delete').click(function () {
var t = this;
$.post("test2.php", { id : txt }, function () {
$(this).html("ready");
});
});
@Carlos, I've no idea what you're trying to achieve without any context, but here's a guess:
This code won't act as you expect:
Because
thisisn't what you think it is. Either run the selector again or point it to the right variable, e.g.Hi, UR artice userful, but I get some probelm, can U help me to fix it ? thanks.
when I user jQuery ajax function.
..............
.............
some code over here.....
@Vincent - I'm not sure if your comment cut short or not, but assuming it didn't I would suggest the problems(s) may be here (keeping in mind I don't have much context to go with):
1) Using 'xxxx.prototype.callback' - might be simpler and lighter on the DOM(?) to just use something like:
2) Since the XML is just data and not functional code, I would expect this:
To break because the XML 'item' node won't have a method called createMarker on it.
I would strongly recommend using [Firebug](http://getfireubg.com) with the 'break on errors' options (in the script tab) turned on.
Good luck.
[...] the “this” keyword in javascript (specifically, using the jQuery library–Thanks, Remy Sharp!), I stumbled across his Last.fm “Recent Albums” widget. They also offer this little [...]
[...] started to look at the this keyword to see if that would help. Learning jQuery’s What is this? post clarified a lot of my [...]
As pointed on another comment, this article brings valuable knowledge to those who are starting to 'uncarefully' mix DOM and JQuery. Thanks.
You can still use this type of code which can use the element's "this", however you still need an id:
This was a very useful article. It definitely clears up the weird and changing jQuery behavior of the keyword 'this' in callback functions and own jQuery functions. Thank you! Ódýr Vefhýsing.
Thanks Remy. A simple article but just what I needed to get started with jQuery!
Thanks Buddy, you have saved my time. I was mucking around with 'this' problem inside a jQuery function. Thanks alot.
Hello,
sorry, but simply cant get this to work. I have a couple of DIV´s with class ".day_group", within these div´s one -heading and one -list that is by default hidden. What I am trying to do is to make the -list to show when you click the - but only in this -section.
I tried this, but this opens all -lists, of course. Tried with "this", but no go. Pls, anbody help. Thx!
$('foo') is an array of matched elements, as you say, but what about when no elements match? If I call $().myPlugin(), what kind of object is 'this' in the myPlugin function?
I'm asking because I am trying to detect that situation happening from within my plugin, but I cannot for the life of me see how to test for that. My guess is that 'this' is an empty jQuery object, but how would I test for that? How would my plugin be able to tell whether it was called up using $().myPlugin() or $('foo').myPlugin()?
It this boils down to this problem: how can I tell whether a jQuery object (which I believe is what 'this' always will be), inside my plugin function, has matched any elements or not?
Thanks!
Regarding my question, I think I have found the answer (is it not always the case when posting a question, that the answer is discovered?):
The three instances I wanted to detect, along with the condition to detect them, are:
1. $().myPlugin()
this.length == 1 && this[0].nodeName == '#document'
2. $('#invalid-selector').myPlugin()
this.length == 0
3. $('#valid-selector').myPlugin()
this.length > 1 || (this.length == 1 && this[0].nodeName != '#document')
Hope that helps someone! Sorry if it is not *entirely* relevant to the original post.
this;
$(this)
can u tell me the returning object in these cases
I was having the same problem as Tyson, and had spent hours trying to find a solution. I'm in the process of writing my first decent sized OOP application, and I was tearing out my hair trying to figure out why 'this' wasn't doing what it should within the jQuery ajax method. Thanks for a great post.
Jepp, as Tyler and Cody it fixed my problem when using colorpicker plugin on several input fields. (If you try my site don't hang me for the jquery design i'm borrowing while developing. Its just a very bad wysiwyg website generator )
Hey thank you, but I can't use your solution in this Script.
As href I'll get 'undefined'. What can I do? Thank you very much!
//edit: Just I've found a Solution:
Thank you so much, I was tearing my hair out and this short article fixed everything.
Very new t JQuery!!
Starting/Trying to understand
$(this)but a way to go.So
$(this).something("varname",varvalue)within a JQuery statment, varvalue is a string, but how would I extract a value.
eg.
varvalue=500;
mynamedvarvalue =$(this).something("varname",varvalue);
//where named var would equate to 500 not 'varvalue' (a string)
TIA.
Paul
what is this? took it from jquery code
$('ul:first',this)
Oh my god, you change the this object!!!! But, when I need of javascript this default? What I do? I'm dificulty with your this. I need default javascript this.
you can help me?
@Aimberê - erm, no, I didn't change anything. However, if you're after the default
thisobject, you'll obviously be needing thewindowobject. I'd recommend only using this when you're working within a specific context, such as an event, i.e. don't usethiswhen you meanwindow.no no. Off course, the default this js is the window object, but in jQuery the this context is modified, the this default haver other context, beyond the window. you can see this when the jQuery is included in your application. Create a script tag and write this:
for (var x in this)
alert(x);
the objects in x are distincts in both cases.
I expressed in my last comment wrong, when I say default this, I should have said, the default context of this. Is very simple, execute following.
http://pastie.org/586211
This cade was tested in All engines and run perfectly, but when I was put in application. BUMMMM. the jquery interpreted differently.
fault of this object.
tests the application and tell me the performance on your machine, please.
thanks.
[]
@Aimber - sorry, I don't really understand what you're trying to achieve. jQuery doesn't modify
thisin anyway, it just sets the context against a particular element when you're inside the event handlers (but this is normal behaviour when you're usingaddEventListener).I see you're modifying the
Objectprototype (which is generally a bad idea), but I don't see what the issue is with the code, and how it relates to jQuery, and how you're inside jQuery to be getting confused withthis.Note that you've also got some global leakage there, e.g.
Meis a global in your code.Sorry I can't be more help.
I particularly do not like to use jQuery, it is to work with the DOM with javascript and not the object but this is changed. with a simple test you can see it. As you well noted, there is nothing wrong with the code, even with me being global (forgot the var). I know that is not normally very good add methods directly to the objects of language but nothing that affects the normal execution of the code. and in my code realmetne there is no line of jQuery, but its inclusion now change the context of the objects. I could very well do so:
Object.prototype.destroyyyyy = function (object){...anyway...};
But this is inelegant and unnecessary in the context of js standard. the big problem of jQuery is that it much thought and forgot the DOM in javascript. and we should be doing to gamiarras concert.
but still, thank you for having tried.
[]'s
Thank you for this explaination, it helps a lot (and fast !)
Thanks for the great article, found a typo:
"The first refers to a to a DOM"
Oooh, this is the first I've heard of console.log(); My life just got so much better.
Very simple to understand and also very important is this :o)
BEFORE ES5 when calling global functions 'this' inside them is/was set to the 'window' object
// before ES5, returns true
function global () { return this === window; }
AFTER ES5 . this in globally called function is set to 'null' !
// for ES5, returns false
function global () { return this === window; }
// for ES5, returns true
function global () { return this === null; }
Actually very wellcome change. Because it simplifies writing ECMAScript code which needs to work unchanged inside or outside of browsers.
Hope this helps, more than it confuses ;o)
--DBJ
PS: ES5 is a common acronym for ECMA-Script 5 Specification. The latest official revision of the language. An Standard since Dec 2009. All browsers are quickly heading towards ES5.
Epiphany moment: 'this' is a jQuery object when you are inside your own jQuery functions.
Thanks!
Not sure where to post this, so I'll put it here since this is where I noticed it:
The "related posts" block on this page is not escaping apostrophes (and you enclose your attributes in them for some reason...) so one of the A tags' title attribute is broken:
(Hopefully that comes out alright. -- EDIT: Argh, it did the first time, now it isn't.)
Thanks for the good explanation, but this is Terrible News. I have a class structure that should use jQuery and jQuery-UI in "object, draw yourself!" kind of methods. I really need 'this' to point to the object within/from which the function is executing to access all data needed to visualize the object. Or at least have *some* way of accessing it in the callbacks. Either of these two patterns would be OK:
1: Don't reassign this. Instead give access to jQuery object through explicit callback parameter:
jQuery.ajax({..., success:function(response, jq_this){...}, ...})
2: Reassign this *and* let user pass arbitrary data to all callbacks:
jQuery.ajax({..., success:function(response, userdata){...}, userdata:this, ...})
Neither is supported? Why?!?! Am I missing something or will I have to resort to global variables to hold important stuff? Like so:
true_this = this;
jQuery.ajax({..., success:function(response){ jq_this=this; this=true_this }, ...});
I'll answer my own question since I now seem to have figured out how to do this. It *is* possible to set the context for callbacks in various ways, depending on the callback:
Use the following pattern for jQuery.ajax():
function X(x) {
this.x = x;
this.y = function() {
jQuery.ajax({..., context:this, success:function(response) {
/* 'this.x' points to X.x as it should */
}, ...});
}
}
Use the following pattern for jQuery.bind():
function X(x) {
this.x = x;
this.y = function() {
jQuery(...).bind('click', {user:this}, function(event) {
var true_this = event.data.user;
true_this.z();
});
}
this.z = function() {
/* 'this.x' points to X.x as it should */
}
Functions that don't support any kind of user passable context must not be used. Unfortunately this seems to include most convenience forms of the most basal functionality in jQuery.
Hi,
+1 for Klas comment : "this" is exactly the major issue we encounter with jQuery !
If this if reassigned each time you enter a function or a loop, then how can you reference the object you are implementing ? Is the only solution adding stupid global variables like Klas suggested ?
Mootools offers an elegant solution to this problem (see function bind() in Mootools). Is there some kind of equivalent for jQuery ?
Thank you for this useful post anyway.
Hi again
I was writing my previous post when Klas published his solution. Thank you Klas.
The "put your context as a data event parameter" is also a solution. This is also unelegant because your callback is bound to be event designed (you cannot bind a simple function and pass simple parameters to an event). It seems like another jQuery problem to me...
Right, the .bind() pattern breaks down easily if you're not careful. I resolved to put absolutely everything in classes to make sure I can always let 'this' have a sensible value (i.e. never the document and certainly never anything jQuery).
I'll just say it's rather hard to fathom that jQuery should be the only DOM manipulation framework (with any market share anyway) that doesn't dabble with DOM extensions or forfeit backwards compatibility otherwise.
Does anyone have a nice pattern for keeping a sensible value of 'this' during element looping? jQuery.each() doesn't take a context parameter so it's the same old problem again. What to do?
Hi Remy,
Thanks for this post, it's been useful to me on more than one occasion now ;)!
However, I'm still having a hard time with "this", not necessarly the jQuery this, but the javascript one in general.
I have a global object where I store my application. I then define some variables and functions which are stored as properties of my applications object (I think this means i'm using the method invocation pattern here, but i'm not 100% sure). One such function is:
setupListeners : function() {
var that = this;
$(this).bind('listen', function(event, that) {
log(event.type + " bound!");
$(that).listen();
});
$(this).trigger('listen');
},
the ".listen()" refers to another function defined in the same way in my application object, and i'm trying to bind my listen() function to a custom event on my application object. The listen command will listen for some data via ajax, then handle the response, and then trigger the listen event again so another ajax request will be made and so on.
The problem i'm having is that the "this" seems to go out of scope when inside jQuery's bind method. As you can see, i tried to make a reference to "this" before calling bind and using that inside the bind function, but it just goes out of scope when the bind method is entered, and so the variable shows as "undefined" in firebug.
Do you have any idea what my problem might be, it's literally blowing my mind 8-).
Many thanks for a great post and a great blog :). I'll also add a thanks for all your jQuery 4 Designers stuff, because i've followed many of your videos there in the past and they have been really helpful in helping me understand more jQuery.
Many thanks,
Kind regards,
Will.
Thank you! You explained $(this). simply and effectively, just saved me SO much time!
maybe this can be useful..
$(this)[0] == this
Basically every time you get a set of elements back jQuery turns it into an array. If you know you only have one result, it's going to be in the first element.
$("#myDiv")[0] == document.getElementById("myDiv");
Hi,
I thought that you'd like to know that Mr. James Harvey over at alteredpixels.net has stolen this blog post and published it under his name in "open source webmagazine." http://opensourcewebmagazine.com/article/index/article_id/13 he's also listing it on his Linkedin profile under his publications http://www.linkedin.com/in/jchharvey
Much of the content on his blog is "borrowed" from other authors, including content that he submits to third party sites.