Explain Codes LogoExplain Codes Logo

What does 'var that = this;' mean in JavaScript?

javascript
javascript-best-practices
javascript-advanced
javascript-closures
Alex KataevbyAlex KataevΒ·Dec 10, 2024
⚑TLDR

In JavaScript, we use var that = this; to preserve reference to the current context (this) within nested functions like callbacks, where this could refer to an entirely different object. The variable that therefore acts as an alias of this, holding the reins to the original context.

Code Sample:

function MyCounter() { var that = this; // Saving 'this' in 'that', just in case 'this' gets lost πŸ˜‰ this.count = 0; this.increment = function() { setTimeout(function() { that.count++; // 'that' knows what it's doing. Trust 'that'. πŸ‘ console.log(that.count); // Correctly outputs the incremented count }, 1000); }; } var counter = new MyCounter(); counter.increment(); // Pops out: 1 after 1 second

Note: Without our friend that, the setTimeout callback's this would point to window (or undefined in strict mode), not the MyCounter instance.

Deep dive into 'var that = this;'

Clearing the air around 'this'

In the quirky world of JavaScript, this doesn't always refer to what you think it does. Its behavior is dynamic and greatly influenced by how functions are created or invoked.

Seeing 'var that = this;' in action

In event handler functions, this can sometimes point to objects like document or window, or the DOM element triggering the event, instead of your much-loved object context. Here, that is your unsung hero.

Event Handlers Situation:

function Button() { this.clicked = false; this.click = function() { this.clicked = true; // 'this' should refer to the Button object }; } var btn = new Button(); document.getElementById('my-btn').addEventListener('click', btn.click); // But alas! 'this' has other plans.

Here, without var that = this;, clicked would point to the DOM button, not the Button instance.

Say hello to descriptive aliases

For the sake of clarity and readability, consider using descriptive aliases like self, clickedEl, etc. The name you choose shouts out what the reference points to.

Keeping 'this' from global scope

By locking that with the right reference, we prevent this from falling back to the global object (in non-strict mode) or undefined (in strict mode). Phew!

'that' in closures

In closures, that plays a crucial role in ensuring that functions neatly wrapped inside have the correct reference to the parent scope's this.

Modern siblings of 'var that = this;'

Good news! Modern JavaScript provides alternatives like arrow functions, Function.prototype.bind, call(), and apply(), which help you maintain context without the need for a separate 'that' variable.

Trudging through 'var that = this;' in real-world code

When 'that' becomes the savior

In asynchronous scenarios like Ajax calls or promises, that is πŸ¦Έβ€β™‚οΈ: ensuring the correct object instance context persists, despite delays or timing shifts.

AJAX Example:

function DataFetcher() { var that = this; // 'that' gears up for the showdown! this.data = null; this.fetch = function() { $.ajax({ url: 'api/data', success: function(response) { that.data = response; // 'that' is on point! } }); }; }

The dark side

Over-reliance on var that = this; can inflate your code. Be smart: understand when to use call(), apply(), and bind() to explicitly set this, thus cutting down the need for that.

Words of wisdom from the wise

Douglas Crockford, our JavaScript guru, advocates a clear coding style with nicely named aliases like that. It promotes readability and easy access to object properties.

Evolving with JavaScript

ES6 arrow functions lessen the dependency on var that = this;. These cool kids do not bind their own this but inherit the this value from their surroundings:

function Timer() { this.seconds = 0; setInterval(() => { this.seconds++; // 'this' is lexically bound to Timer. Arrow functions for the win! πŸŽ‰ }, 1000); }