Reputation:
From what I understand, this
inside of a function refers to the object invoking the function. So, for instance, in
myObj = { name : "Charlie", getType : function() { return typeof(this); } };
console.log(myObj.getType());
the object invoking the function getType
is myObj
and therefore typeof(this)
is typeof(myObj)
.
Why, then, do I always see $(this)
inside jQuery functions? For instance, in
$('.not-taller-than-50-pixels').each(function()
{
if ($(this).height() > 50) $(this).height(50);
});
doesn't $('.not-taller-than-50-pixels')
return an array of jQuery objects and so inside the each
the invoking function is a jQuery object and so this
would refer to that jQuery object and I can simply write if (this.height() > 50) this.height(50);
???
Upvotes: 0
Views: 76
Reputation: 21482
doesn't $('.not-taller-than-50-pixels') return an array of jQuery objects
No, $('.not-taller-than-50-pixels')
does not return an array of JQuery objects. It returns a single JQuery object, which may wrap zero, one, or many DOM elements.
and so inside the each the invoking function is a jQuery object and so this would refer to that jQuery object and I can simply write if (this.height() > 50) this.height(50); ???
The callback function passed to .each()
is invoked for each of the DOM elements wrapped by the JQuery object, and when the callback function is invoked, the DOM element is used as the context. That is, inside the callback function this
will reference the DOM element, not a JQuery object.
This is stated in the JQuery documentation for the .each()
function:
When called it iterates over the DOM elements that are part of the jQuery object. Each time the callback runs, it is passed the current loop iteration, beginning from 0. More importantly, the callback is fired in the context of the current DOM element, so the keyword
this
refers to the element.
Upvotes: 1
Reputation: 95026
From what I understand, this inside of a function refers to the object invoking the function.
that is correct, if the function is being called as a property of that object. However, in your case, your jQuery collection isn't invoking the function as a property of the jQuery collection, instead it's invoking the function using either .apply
or .call
to set its context to the element currently being iterated over.
https://github.com/jquery/jquery/blob/1.9.1/src/core.js#L628
It works similar to the way Array.prototype.forEach
does. I assume that similarity is on purpose so that it seems familiar to most developers who are also familiar with native methods.
Here's an example more inline with your first snippet that WILL act the way you were expecting:
$.fn.alertHeight = function () {
alert(this.height());
}
$('body').alertHeight();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<p>Hello World!</p>
Because the function is stored on the prototype of $
, and invoked as a property of a jQuery collection (which is an instance of $
,) this
refers to the jQuery collection, thus allowing us to use this.height()
directly to get the height of the first element in the collection.
Upvotes: 3
Reputation: 5454
We use the $(this)
because otherwise the this
doesn't have a getter/setter method .height()
. $()
gives all selected elements access to jquery methods which plain javascript equivalents don't have. try console.log($(this), " VS ", this);
remember that $()
is a function.
Upvotes: 1