toxalot
toxalot

Reputation: 11820

Is it preferable to use "this" or "that" (where var that = this)?

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

Answers (5)

zgr024
zgr024

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

toxalot
toxalot

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

josh3736
josh3736

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

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385204

There isn't any reason, other than the standard subjective rationales of consistency and meaningful variable names.

Upvotes: 2

Pointy
Pointy

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

Related Questions