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)
Introducing HTML5
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.)