user5286438
user5286438

Reputation:

Why do we use $(this) inside a function acting on a jQuery object?

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

Answers (3)

John S
John S

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

Kevin B
Kevin B

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

Todd
Todd

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

Related Questions