Reputation: 11820
I'm fairly new to JavaScript and I'm cleaning up some JavaScript code I downloaded. One of the inconsistencies in this code is mixed usage of both this
and the local variable that
that references it.
An example code snippet (private method within a jQuery UI widget):
_populateLists: function(options) {
//do stuff with this
var that = this;
options.each(function(index) {
//use both this AND that, they are different in this scope
});
//here this and that are the same thing
//I want to be consistent, is one preferable over the other?
},
In many places throughout the code, where the scope is such that this === that
, there is mixed usage, even within the same line of code.
For the sake of readability and maintainability, is it preferable to use this
or that
?
Note: I realize a lot of these types of things depend on developer preference. But before I decide to rewrite the code to use one over the other, I'd like to understand any reasoning if/why one would be preferred over the other.
EDIT: In this script, I think the only reason this
is being assigned to a local variable is so that it can be referred to from within the inner closure.
Upvotes: 3
Views: 632
Reputation: 1173
When assigning a variable to $(this)
when using jQuery, it is preferable to use $this
as it refers to a jQuery object ( $
). It is commonly used when $(this)
no longer refers to the parent object when in the scope of another function.
The variable name however does not matter and simply refers to the object assigned. We could use $this
, $that
, $obj
, that
, obj
, button
etc. as our variable name, however this
in javascript is a reserved word referring to the object in the current scope so we cannot use this
as the variable name. You cannot assign any type of value to this
or $(this)
.
Example...
this = 'something'; // or
$(this) = 'something';
Both of the above statements will throw an exception.
An example using $this = $(this);
is shown below
To change the html of a button with the id of "someButton" after a successful jQuery post...
$('#someButton').click(function() {
var data = $('form').serializeArray();
// some validation or something
$this = $(this);
// note the lack of the var command to
// globalize $this within the click function
$.post('somePage',data,function(html) {
$this.html(html);
// identical to $('#someButton').html(html);
});
});
Upvotes: 0
Reputation: 11820
If the purpose of assigning this
to a local variable is to achieve semantics, then it would make sense to use a semantic variable name and then use the variable rather than this
.
But since the purpose of assigning this
to a local variable in this scenario is to cache it for use in an inner function, I think it's more readable/semantic to continue to use this
in the outer scope.
While that
is not normally a very good variable name, I think the meaning remains clear in this scenario. In my mind, in the inner scope, that is to this as parent is to self.
And since this is a jQuery UI widget, I looked at the source of some of the standard widgets that 'ship' with jQuery UI. It seems to be a standard convention to use this
throughout except when needing to refer to the this
of the outer scope. In the latter case, this
is cached in a variable named that
. Even when the local variable exists, it's only used in the inner scope.
Example for clarity:
_populateLists: function(options) {
var that = this; //we'll need `this` within a closure later
//do some stuff with `this`
options.each(function(index) {
//do stuff with `this` AND `that`
//`that` is the `this` of the outer scope
});
//do some more stuff with `this`
},
If consistency is the goal, then it makes sense to follow the same convention used by standard jQuery UI widgets.
Upvotes: 0
Reputation: 144922
The reason that the value of this
is commonly assigned to a local variable is so that you can close over that value and use it inside a nested function.
this
is a special variable and somewhat different from normal local variables in that it is automatically set to the object upon which a function was called (if any); otherwise, the global object. However, this intrinsic value of this
is somewhat muddied by jQuery's liberal use of call
and apply
, which allow the caller to specify the value of this
.
In a nested function, this
does not inherit the value of its parent's this
in the same way it would inherit a parent's local variables through the scope chain.
Because of this, we have to stash the value of this
in a local variable if we need it inside a nested function, such as the each
callback in your example.
var a = { fn: function() {
// here, `this` is the object `a`
var x = this;
function b() {
// here, `this` is `window` because `b` is invoked with no context
// ...but we still have access to `x`, whose value would be `a`
}
b();
}};
a.fn(); // by invoking `fn` as a property of `a`, we implicitly set `fn`'s
// `this` to `a`.
// Compare to:
var f = a.fn;
f(); // we now invoke `fn` with no context, so its `this` will be `window`.
a.fn.call(window); // or by specifying context explicitly
Of course, when you're still in the parent scope, this
will still equal that
(or self
or whatever). At first glance, it may seem like there's no difference between the two, but there is one important performance impact:
Minification. If you assign this
to a local variable, all references to that variable can be reduced to one character. References to this
cannot. Compare this minified output:
function a() {this.w=1;this.x=2;this.y=3;this.z=4;}
function b() {var t=this;t.w=1;t.x=2;t.y=3;t.z=4;}
With 4 references to this
, you save bytes by using a variable. If you have to capture this
for an inner function anyway, using the local variable instead of this
in the outer function gets you savings even with a single reference.
Upvotes: 4
Reputation: 385204
There isn't any reason, other than the standard subjective rationales of consistency and meaningful variable names.
Upvotes: 2
Reputation: 413757
If you go to the trouble of assigning this
to a local variable, it's probably a good idea to use it, especially if you've given the local variable a useful name:
$('body').on('click', '.something', function() {
var clicked = this;
// now "clicked" is the element clicked on
});
for a jQuery example, but it's the same issue regardless of library or in raw JavaScript. Personally I think "that" is a pretty weak variable name in almost all cases.
Upvotes: 0