Monday, 19 June 2017

javascript - What does "this" mean in jQuery?




In jquery, what does this means and when it is used?


Answer



this in JavaScript is very special and powerful. It can mean just about anything. I cover some of it here and here, but it's really worth finding a good tutorial on JavaScript and spending some time with it.



Let's look at jQuery's use of it first, then talk about it more generally in JavaScript (a bit).



In jQuery, specifically




In code written with jQuery, this usually refers to the DOM element that's the subject of the function being called (for instance, in an event callback).



Example jQuery event callback (what this is is covered in the .bind docs):



$("div").click(function() {
// Here, `this` will be the DOM element for the div that was clicked,
// so you could (for instance) set its foreground color:
this.style.color = "red";

// You'll frequently see $(this) used to wrap a jQuery object around the

// element, because jQuery makes lots of things a lot simpler. You might
// hide the element, for example:
$(this).hide();
});


Similarly, various jQuery functions that act on all of the elements matched by the current jQuery selector can optionally accept a function, and when that function gets called, this is again the DOM element in question — for instance, the html function allows this:



// Find all divs inside the `foo` element, and set
// their content to their CSS class name(s)

// (Okay, so it's a hokey example)
$("#foo div").html(function() {
return this.className;
});


Another place jQuery uses this is in the callback on jQuery.each:



var a = ["one", "two", "three"];
jQuery.each(a, function() {

alert(this);
});


...which will alert "one", then "two", then "three". As you can see, this is a totally different usage of this.



(Confusingly, jQuery has two functions called each, the one above which is on the jQuery/$ function itself and always called that way [jQuery.each(...) or $.each(...)], and a different one on jQuery instances [objects] rather than the jQuery/$ function iself. Here are the docs for the other one, I don't discuss the other one in this answer because it uses this the same way html and event callback do, and I wanted to show a different use of this by jQuery.)



Generically in JavaScript




this refers to an object. Update: As of ES5's strict mode, that's no longer true, this can have any value. The value of this within any given function call is determined by how the function is called (not where the function is defined, as in languages like C# or Java). The most common way to set up this when calling a function is by calling the function via a property on the object:



var obj = {};
obj.foo = function() {
alert(this.firstName);
};
obj.firstName = "Fred";
obj.foo(); // alerts "Fred"



There, because we called foo via a property on obj, this was set to obj for the duration of the call. But don't get the impression that foo is in any way married to obj, this works just fine:



var obj = {};
obj.foo = function() {
alert(this.firstName);
};
obj.firstName = "Fred";
obj.foo(); // alerts "Fred"

var differentObj = {};

differentObj.firstName = "Barney";
differentObj.bar = obj.foo; // Not *calling* it, just getting a reference to it
differentObj.bar(); // alerts "Barney"


In fact, foo isn't intrinsically tied to any object at all:



var f = obj.foo; // Not *calling* it, just getting a reference to it
f(); // Probably alerts "undefined"



There, since we didn't call f via an object property, this wasn't explicitly set. When this isn't explicitly set, it defaults to the global object (which is window in browsers). window probably doesn't have a property firstName, and so we got "undefined" in our alert.



There are other ways to call functions and set what this is: By using the function's .call and .apply functions:



function foo(arg1, arg2) {
alert(this.firstName);
alert(arg1);
alert(arg2);
}


var obj = {firstName: "Wilma"};
foo.call(obj, 42, 27); // alerts "Wilma", "42", and "27"


call sets this to the first argument you give it, and then passes along any other arguments you give it to the function it's calling.



apply does exactly the same thing, but you give it the arguments for the function as an array instead of individually:



var obj = {firstName: "Wilma"};

var a = [42, 27];
foo.apply(obj, a); // alerts "Wilma", "42", and "27"
// ^-- Note this is one argument, an array of arguments for `foo`


Again, though, there's a lot more to explore about this in JavaScript. The concept is powerful, a bit deceptive if you're used to how some other languages do it (and not if you're used to some others), and worth knowing.



Here are some examples of this not referring to an object in ES5's strict mode:



(function() {

"use strict"; // Strict mode

test("direct");
test.call(5, "with 5");
test.call(true, "with true");
test.call("hi", "with 'hi'");

function test(msg) {
console.log("[Strict] " + msg + "; typeof this = " + typeof this);
}

})();


Output:



[Strict] direct; typeof this = undefined
[Strict] with 5; typeof this = number
[Strict] with true; typeof this = boolean
[Strict] with 'hi'; typeof this = string



Whereas in loose mode, all of those would have said typeof this = object; live copy.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...