Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the context of the 'this' keyword with jQuery

Tags:

jquery

As a jQuery neophyte I am somewhat confused by the different contexts in which the this keyword is used. Sometimes it refers to a DOM element e.g. this.id and sometimes it refers to a jQuery object e.g. $(this).val().

Remy Sharp's blog post is helpful but I would like to know how you would explain the difference to a novice. Is the difference strictly a jQuery issue or common to all Javascript?

Thanks for all the responses so far - great stuff, I will pick an answer tomorrow. Here is another blog post I subsequently came across that was also helpful: What is this? by Mike Alsup.

like image 243
eft Avatar asked Feb 16 '09 02:02

eft


4 Answers

Remy Sharp's post is confusing if you don't read it carefully, in my opinion. The meaning of this never changes. In the example you gave, there were 2 uses of this. As a DOM element in an event:

$('a').click(function() {
    alert(this.tagName);
});

and wrapped as a jQuery object in an event:

$('a').click(function() {
    alert($(this).val());
});

If you read the 2 snippets above very carefully you'll notice that this never changes meaning. It always refers to the DOM element. The difference comes in how it is used.

In jQuery, by default, this refers to the DOM element (not a jQuery object) which triggered an event. In the second code snippet above, it is still the same DOM element, only it is wrapped in a jQuery element by wrapping $() around it. As with any argument to the jQuery constructor, passing this into the constructor transforms it into a jQuery object.

I think the confusion comes in when Remy starts talking about jQuery plugins in the same article as jQuery events. jQuery plugins are something that people rarely write and frequently use. When writing a jQuery plugin, you're working within the context of the jQuery object prototype. In this case, you're using the word this to refer to the plugin you're writing. In normal use-cases, you won't be writing plugins often so this is a much less common scenario. When not in the scope of the plugin, you can't use this to refer to the jQuery object.


In the JavaScript language, the keyword this refers to the current instance of an object in JavaScript. When being used in a JavaScript prototype, it refers to the instance of the prototype. Depending on the browser, when using the non-jquery event model, this also refers to the DOM element. Because some browsers (Internet Explorer) don't refer to this as the DOM element in an event, it makes working with events difficult. To get around this, jQuery performs some JavaScript magic that always makes this refer to the DOM element which triggered the event. That is (one of the many) reasons to use a JavaScript framework instead of rolling your own.

like image 187
Dan Herbert Avatar answered Sep 21 '22 14:09

Dan Herbert


Don't forget that if you ever aren't sure what the "this" is in any given context, you can diagnose it in Firebug using the console:

console.log("This is: " + this)

If you're using jQuery (as you mentioned you were) you can always ensure that "this" is still a jQuery object by doing this:

this = $(this);

Then, back in the console, you can see what the jQuery object of "this" is by logging it in Firebug:

console.log("The jQuery This is: " + $(this))

Lastly, since we're talking about jQuery, there are some instances where "this" changes. For instance, when you're doing a callback after an animation or a fadeIn or fadeOut. In that context, the "this" would refer to the item receiving the effect.

Just remember, if you're ever not sure what "this" is... ask the Firebug. The Firebug sees all. The Firebug knows all.

like image 34
Jeremy Ricketts Avatar answered Sep 23 '22 14:09

Jeremy Ricketts


sometimes it refers to a jQuery object e.g. $(this).val().

this here refers to a DOM element; the $() function call is what wraps the DOM element in a jQuery object. For jQuery event callbacks, this will (almost?) always refer to a DOM element. When writing a function that extends jQuery, that can be called with $('select').myfunc(), this will refer to a jQuery object.


In JavaScript in general, this applies when a function is called as a property of an object (the method-looking invocation). So given the function:

function foo() {
    doSomethingWith(this);
}

var obj1 = {'foo': foo};
var obj2 = {};
obj2.myFoo = foo;

obj1.foo(); // calls function foo(), with 'this' set to obj1
obj2.myFoo(); // calls function foo(), with 'this' set to obj2
foo();      // calls function foo(), with 'this' set to the global object
            // (which, in a browser, is the window object)
foo.apply(new Date()); // calls foo(), with 'this' set to a Date object

So, in Javascript, the kind of object that 'this' refers to in a function depends more on how a function is called than the actual definition of the funciton.

like image 31
Miles Avatar answered Sep 22 '22 14:09

Miles


jQuery Proxy might help you to get your answer. You can call a jQuery function and alter what object the this scope refers to.

e.g. something like:

var me = {
  type: "zombie"
  ,test: function() {$('#result').html(this.type)}

};

$.proxy( me.test(), me ); //prints 'zombie'
like image 42
jdog Avatar answered Sep 21 '22 14:09

jdog