jquery this versus $(this) and maybe even $this - javascript

I often see examples of using the keyword this in jquery. Sometimes I see it used with the $ and parenthesis, other times without. And I thought I saw it used with a little of each.
So,
var id = this.attr('id');
var id = $(this).attr('id');
var id = $this.attr('id');
Are these all the same? Is there a preferred way? Is this a javascript thing and $(this) a jQuery thing? If so, where does $this fall?
I know this is probably a total newbie question, but I haven't been able to get the simple, this, by itself, to work. I can only get $(this) to work. I'm not sure if I'm doing something wrong, or if I've been reading examples with typos.

this is a JavaScript thing. It refers to the "context" a function is running in. For most event handlers, it is the ("raw") DOM element that is listening to an event. In other situations it will mean other things; Googling "this in JavaScript" might be enlightening.
I say it is the "raw" DOM element because jQuery is often used to wrap plain DOM elements in a jQuery wrapper, so you can use jQuery methods like attr instead of the usual ones (getAttribute, setAttribute, etc.). This wrapping is accomplished with the $ function, and that's where you see $(this). For example:
this.getAttribute("href")
/* or */ someElement.getAttribute("href")
is the same as
$(this).attr("href")
/* or */ $(someElement).attr("href")
$this or this$ is just a variable name. But, it is often conventional to do an assignment like
var $this = $(this);
The reason for this is to avoid continually invoking the $ function, which is somewhat expensive as it creates a new jQuery wrapper object every time. If you store the wrapped element in a variable, you gain slightly in efficiency.
In rare cases, this might already be a jQuery wrapper. The case that comes up often for me is when writing jQuery plugins. In that case you can do things like this.attr("id") directly, without wrapping it up first, because it's already wrapped. In the usual cases (event handlers, $.each, etc.) the wrapper is necessary.

'this' is a Javascript object keyword for referring to the current object, '$(this)' is the jQuery wrapper function that turns the current object into a jQuery object, and when you see '$this' it usually refers to a variable that the developer created to refer to the $(this) object, it's useful during a $.each loop. For example:
$(function(){
$('a').click(function(){
var $this = $(this); // refers to the $('a') object
$('div').each(function(){
$(this).hide(); // $(this) refers to each 'div' in the loop, not the $('a')
$this.css({ color: 'blue' }); // turns the link element text blue
});
});
});

this is a native Javascript object that refers to the current object. In jQuery functions defined with jQuery.fn., this is a jQuery object by itself. $(this) is jQuery's way of turning a Javascript this into a jQuery object. And $this is just a variable name. If you haven't defined it, it would be undefined.
Here's a good explanation of jQuery's usage of this:
http://www.learningjquery.com/2007/08/what-is-this

instead of calling $(this) multiple times, it's more efficient to store it as a variable, usually called $this so that people know what it is.

Related

what does wrapping a jQuery object with another `$` mean? [duplicate]

I am currently working through this tutorial: Getting Started with jQuery
For the two examples below:
$("#orderedlist").find("li").each(function (i) {
$(this).append(" BAM! " + i);
});
$("#reset").click(function () {
$("form").each(function () {
this.reset();
});
});
Notice in the first example, we use $(this) to append some text inside of each li element. In the second example we use this directly when resetting the form.
$(this) seems to be used a lot more often than this.
My guess is in the first example, $() is converting each li element into a jQuery object which understands the append() function whereas in the second example reset() can be called directly on the form.
Basically we need $() for special jQuery-only functions.
Is this correct?
Yes you only need $() when you're using jQuery. If you want jQuery's help to do DOM things just keep this in mind.
$(this)[0] === this
Basically every time you get a set of elements back jQuery turns it into a jQuery object. If you know you only have one result, it's going to be in the first element.
$("#myDiv")[0] === document.getElementById("myDiv");
And so on...
$() is the jQuery constructor function.
this is a reference to the DOM element of invocation.
So basically, in $(this), you are just passing the this in $() as a parameter so that you could call jQuery methods and functions.
Yes, you need $(this) for jQuery functions, but when you want to access basic javascript methods of the element that don't use jQuery, you can just use this.
When using jQuery, it is advised to use $(this) usually. But if you know (you should learn and know) the difference, sometimes it is more convenient and quicker to use just this. For instance:
$(".myCheckboxes").change(function(){
if(this.checked)
alert("checked");
});
is easier and purer than
$(".myCheckboxes").change(function(){
if($(this).is(":checked"))
alert("checked");
});
this is the element, $(this) is the jQuery object constructed with that element
$(".class").each(function(){
//the iterations current html element
//the classic JavaScript API is exposed here (such as .innerHTML and .appendChild)
var HTMLElement = this;
//the current HTML element is passed to the jQuery constructor
//the jQuery API is exposed here (such as .html() and .append())
var jQueryObject = $(this);
});
A deeper look
thisMDN is contained in an execution context
The scope refers to the current Execution ContextECMA. In order to understand this, it is important to understand the way execution contexts operate in JavaScript.
execution contexts bind this
When control enters an execution context (code is being executed in that scope) the environment for variables are setup (Lexical and Variable Environments - essentially this sets up an area for variables to enter which were already accessible, and an area for local variables to be stored), and the binding of this occurs.
jQuery binds this
Execution contexts form a logical stack. The result is that contexts deeper in the stack have access to previous variables, but their bindings may have been altered. Every time jQuery calls a callback function, it alters the this binding by using applyMDN.
callback.apply( obj[ i ] )//where obj[i] is the current element
The result of calling apply is that inside of jQuery callback functions, this refers to the current element being used by the callback function.
For example, in .each, the callback function commonly used allows for .each(function(index,element){/*scope*/}). In that scope, this == element is true.
jQuery callbacks use the apply function to bind the function being called with the current element. This element comes from the jQuery object's element array. Each jQuery object constructed contains an array of elements which match the selectorjQuery API that was used to instantiate the jQuery object.
$(selector) calls the jQuery function (remember that $ is a reference to jQuery, code: window.jQuery = window.$ = jQuery;). Internally, the jQuery function instantiates a function object. So while it may not be immediately obvious, using $() internally uses new jQuery(). Part of the construction of this jQuery object is to find all matches of the selector. The constructor will also accept html strings and elements. When you pass this to the jQuery constructor, you are passing the current element for a jQuery object to be constructed with. The jQuery object then contains an array-like structure of the DOM elements matching the selector (or just the single element in the case of this).
Once the jQuery object is constructed, the jQuery API is now exposed. When a jQuery api function is called, it will internally iterate over this array-like structure. For each item in the array, it calls the callback function for the api, binding the callback's this to the current element. This call can be seen in the code snippet above where obj is the array-like structure, and i is the iterator used for the position in the array of the current element.
Yeah, by using $(this), you enabled jQuery functionality for the object. By just using this, it only has generic Javascript functionality.
this reference a javascript object and $(this) used to encapsulate with jQuery.
Example =>
// Getting Name and modify css property of dom object through jQuery
var name = $(this).attr('name');
$(this).css('background-color','white')
// Getting form object and its data and work on..
this = document.getElementsByName("new_photo")[0]
formData = new FormData(this)
// Calling blur method on find input field with help of both as below
$(this).find('input[type=text]')[0].blur()
//Above is equivalent to
this = $(this).find('input[type=text]')[0]
this.blur()
//Find value of a text field with id "index-number"
this = document.getElementById("index-number");
this.value
or
this = $('#index-number');
$(this).val(); // Equivalent to $('#index-number').val()
$(this).css('color','#000000')

Writing JavaScript Functions - Should I Pass jQuery Objects as arguments?

I'm curious from both a performance and a "best practices" standpoint. I'm using a lot of jQuery in my JavaScript, and often find myself passing jQuery objects as arguments into functions I'm writing. Is it more efficient/effective to pass the selector string rather than the actual jQuery object as the argument? Is this just a stylistic difference, or are there any good reasons to use one method over the other?
Using jQuery objects in arguments:
function updateSelectOptions(optionsData, $selectElement) {
// function code
}
Or using a selector string as the argument:
function updateSelectOptions(optionsData, selectorString) {
var $selectElement = $(selectorString);
// function code
}
You should accept anything the jQuery constructor can for maximum flexibility.
Re-wrapping a jQuery collection doesn't blow up, so I often use something like...
var fn = function(elems) {
var $elems = $(elems);
};
That way, you can accept a jQuery collection, selector string or reference to native DOM element(s).
If you find yourself wanting to write a function that takes a jQuery object as a parameter, why not just make your function a jQuery plugin? It's pretty easy, and it makes using the function fit in with the rest of your jQuery code.
Instead of
function something(jq) {
jq.css("color", "red");
});
you'd write
$.fn.something = function something() {
this.each(function() {
$(this).css("color", "red");
});
return this;
};
Now when you want to turn something red, you can just say
$(".whatever").something();
The value of this in a jQuery plugin is the jQuery object that's being passed along the chain. You don't have to wrap it with $(this). Unless your function is something that returns some value, it's good to return whatever's passed in so that you can use your own plugin in the middle of a dotted chain.
In my opinion, passing the object is fine and would be better for performance.
Why?
Most of the time, the reason for using functions is to reuse code. Hence, if you pass the string (the selector) such as updateSelectOptions(optionsData, selectorString)
every time you call the function and then use that string to select the element:
var $selectElement = $(selectorString);
This will consume more memory, because the element will have to be searched for every function call.
Where if you pass the cached object this element will only be selected and searched for only once.
The second approach remove any reference to the object after the function finished to execute. The first one allow you to keep the reference to the object to manipulate it outside the scope of the function.

using this rather than $(this) in an .each() call

I've done quite a lot of reading this past day to get a deeper understanding of this vs. $(this) and how JS determines this as it interprets, but I still can't figure out one detail of a plugIn I'm analyzing to deepen my knowledge:
$.fn.plugInName = function(options) {
return this.each(function() {
new $.plugInName(this,options);
});
};
Everything I've read indicates that although this.each() is used to call JQuery.prototype.each(), each object should be referred to as $(this) within the each() function, but the above uses regular ol' this, and I can't figure why. The $.plugInName declaration looks like this:
$.plugInName = function(el,options) {
...
}
Any insights anyone may have will be a big help.
EDIT: Here's the full source on GitHub
From MDN:
When a function is called as a method of an object, its this is set to
the object the method is called on.
When you call something like
$('#myDiv').plugInName()
the function is called as a method of the jQuery object $('#myDiv'). So, in this case, this already refers to a jQuery object, thus we don't need the extra $() wrapper.
A common case when we do need $() is when binding events.
$('#myDiv').on('click', function(){
alert('You clicked my div!');
});
The difference here is that the function is called not on $('#myDiv'), but the DOM element that it belongs to. So, here this is a DOM object, not a jQuery object.
Inside the callback function passed to each, this refers to the DOM element, it is not a jQuery object.. which is just what $.plugInName wants. It expects a DOM element.

this and $(this) in widget

What do this and $(this) mean inside a widget method like create?
For example, Having a widget like this,
$.widget("sample.CustomWidget", {
options:{
},
_create: function(){
// Here what do this and $(this) mean
}
});
Thanks in advance,
-Raja.
It basically depends on the caller of the _create method... anyway:
this refers to the 'owner' of the Function
$(this) is the above object wrapped into a jQuery object
see also:
http://www.quirksmode.org/js/this.html
http://www.bennadel.com/blog/1838-Wrapping-The-Window-Object-In-A-jQuery-Wrapper.htm
Within an event handler of a standard jQuery UI-style widget, this will refer to the DOM element related to the event, $(this) creates a jQuery wrapper around this, and the DOM element (again) is available as this.
But when your widget functions are called, typically this refers to the jQuery object on which the function was called, not a specific DOM element. You then operate on the matched set of elements within that jQuery object.
In a method integrated with jQuery:
$.fn.yourFunction = function() {
// ...
};
the value of this is the jQuery object itself. There's no reason, therefore, to wrap this with another call to jQuery, though it doesn't hurt.
In a callback to an event handler:
$('#myButton').click(function() {
// ...
});
the value of this is the target DOM element of the event, or the target object if the event is triggered on something other than the actual DOM.
In other jQuery callback situations, like .each() for example, the value of this is generally determined by the nature of the jQuery object.
The upshot of all that is that inside an integrated-with-jQuery function (first sample), you generally don't wrap this in another call to jQuery; it's already a jQuery object. In all other cases, if you want to use this with jQuery facilities, you do have to wrap it.
In that context, "this" is the actual JQuery widget object, which allows you to query things such as widgetName, widgetEventPrefix etc, whereas "$(this)" is just the JQuery object for "this", which you can't get the widget properties using.
this represents the contructor you are in. For example in a click event, the dom element being clicked, in a function the constructor of function;
function test{
this.b = "hello jupiter";
}
var a = new test();
alert(a.b);
Acctually there is nothing special with $(this). There is a function called $ and "this" is it's parameter, like alert;
$(this);
//just like
alert("some string);

$this vs $(this) in jQuery

I've seen some discussions on SO regarding $(this) vs $this in jQuery, and they make sense to me. (See discussion here for an example.)
But what about the snippet below, from the jQuery website plugin tutorial showing how chainability works?
(function ($) {
$.fn.lockDimensions = function (type) {
return this.each(function () {
var $this = $(this);
if (!type || type == 'width') {
$this.width($this.width());
}
if (!type || type == 'height') {
$this.height($this.height());
}
});
};
})(jQuery);
What does $this represent above? Just when I think I have it figured out ...
$this is just an ordinary variable. The $ character is a valid character in variable names, so $this acts the same as any other non-reserved variable name. It's functionally identical to calling a variable JellyBean.
You usually use var $this = $(this); to avoid creating a new jQuery object more often than necessary. In case of the code below you only create one object instead of two/four. It is completely unrelated to chainability.
You could also call it that, $thi$ or anything else (don't use the latter one though, it's ugly :p) as $ is just a simple character in JavaScript, exactly like a-z are.
this in javascript (usually) represents a reference to the object that invoked the current function. This concept is somewhat fuzzied a bit by jQuery's attempts to make the use of this more user friendly within their .each() looping stucture.
outside the .each(), this represents the jQuery object that .lockDimensions is invoked by.
inside the .each() it represents the current iterated DOM object.
Generally the purpose of storing $(this) in a local variable is to prevent you from calling the jQuery function $() multiple times, caching a jQueryized this should help efficiency if you have to use it multiple times.
$ is simply a valid variable name character and is used as the first character of a variable name usually to queue the programmer that it is a jQuery object already (and has the associated methods/properties available).
This question is actually unrelated to chain-ability, but to maintain chain-ability you should return this so that other function calls can be added, and maintain the meaning of this in those calls as well.
you may have overlooked this line:
var $this = $(this);
Here, $this is just a variable that holds the value of $(this). You can use it interchangeably with $(this) with the benefit that you aren't doing the same lookup over and over.
$this is simply a local variable, named that way to remind you of $(this). It saves the work of creating the jQuery version of this, and you can use it a number of times.
$this is just a local copy of this wrapped in jQuery.
In the long term, keeping a local copy rather than wrapping this each time it is needed is much more efficient.
$this = $(this) is a way to cache the jQuery object. It is expensive to run the jQuery function each time, so storing the output allows you to re-use the selector over and over again without calling jQuery function again.
$this = $(this)
which means that you are assigning the current object to a variable named $this. It is not a keyword.
It is just a variable name.
It just fills $this variable with $(this), so you do not have to lookup for $(this) element every call. It has better performance
var $this = $(this);
It's quite simple: $this = $(this). It's just a shorthand used in the scope of the inner function. The dollar sign is just a character in this case, it doesn't refer to jQuery at all. It might just as well have been named _this or xthis, the $ is just a reminder of what the variable contains.
It may seem pointless, but it eliminates three redundant method invocations (the $() function isn't free) so it is most likely used there for performance reasons.
Inside $.fn.lockDimensions, this is the jQuery object that had lockDimensions called on it.
Inside the .each, this now references the DOMElement in the current iteration of the loop. $(this) wraps the DOMElement in a jQuery object, and var $this = $(this); is just saving $(this) in a variable called $this, so the jQuery constructor doesn't need to be called multiple times (if you were to use $(this) instead).
$ sign is usually used before variable names in JavaScript to differentiate between general value and jQuery object. So here $this just gets the value of $(this) which returns jQuery object of this. $ is just a part of valid variable name.
$this is a variable named $this containing a reference to $(this). A bit pointless IMO.
I want to jump in here, even though I do not have expert jQuery skills.
Countless times I see lines of code or concepts similar to:
var $this = $(this);
So I do a rewrite of it similar to:
var $jims_this = $(this);
And test it. Also I do this to clear up any confusion I might have.
Here is another example of similar poorly explained code:
<style>
a.a { font-weight: bold; }
</style>
Next, add the addClass call to your script:
$("a").addClass("a");
This does work but it is confusing. It could have been written as:
<style>
a.my_bold_class { font-weight: bold; }
</style>
$("a").addClass("my_bold_class");
Jim
You have wandered into the realm of javascript scope and closure.
For the short answer:
this.bar()
is executed under the scope of foo, (as this refers to foo)
var barf = this.bar;
barf();
is executed under the global scope.
this.bar basically means:
execute the function pointed by this.bar, under the scope of this (foo). When you copied this.bar to barf, and run barf. Javascript understood as, run the function pointed by barf, and since there is no this, it just runs in global scope.
To correct this, you can change
barf();
to something like this:
barf.apply(this);
This tells Javascript to bind the scope of this to barf before executing it.
For jquery events, you will need to use an anonymous function, or extend the bind function in prototype to support scoping.

Categories

Resources