What’s Wrong with $(this)? - J Query

Problem
You have an event handler that adds a class to a DOM element, waits one second using
setTimeout(), and then removes that class:

The class gets added when you click, but it never gets removed. You have confirmed that the code inside setTimeout() is being called, but it doesn’t seem to do anything. You’ve used .removeClass() before, and that code looks correct. You are using $(this) the same way in both places, but it doesn’t seem to work inside the setTimeout() call.

Solution

Save this in a variable before calling setTimeout():

Even better, since you’re calling $() in both places, follow the advice in Recipe 5.3 and
copy$(this) to a variable instead of this:

Discussion

What is $(this) anyway, and why doesn’t it always work? It’s easier to understand if you separate it into its two parts, $() and this.
$() looks mysterious, but it really isn’t: it’s just a function call. $ is a reference to the jQuery function, so $() is simply a shorter way to write jQuery(). It’s just an ordinary JavaScript function call that happens to return an object.
this is one of the more confusing features in JavaScript, because it’s used for so many different things. In object-oriented JavaScript programming, this is used in an object’s methods to refer to that object, just like self in Python or Ruby:

In the code for a traditional on event attribute, this refers to the element receiving the event—but only in the attribute itself, not in a function called from the attribute:

As you can see from the third alert(), this is actually the window object inside the function. For historical reasons, window is the “default” meaning of this when a function is called directly (i.e., not called as a method of an object).
In a jQuery event handler, this is the DOM element handling the event, so $(this) is a jQuery wrapper for that DOM element. That’s why $(this).addClass() works as
expected in our “Problem” code.
But the code then calls setTimeout(), and setTimeout() works like a direct function call: this is the window object. So when the code calls $(this).removeClass(), it’s actually trying to remove the class from the window object!
Why does copying this or $(this) into a local variable fix this? (Pun intended.) Java- Script creates a closure for the parameters and local variables of a function.
Closures may seem mysterious at first, but they really boil down to three simple rules:

  • You can nest JavaScript functions one inside another, with multiple levels of
    nesting.

  • A function can read and write not only its own parameters and local variables but also those of any functions it’s nested in.

  • The previous rule always works, even if the outer function has already returned and the inner function is called later (e.g., an event handler or setTimeout() callback).

These rules apply equally to all functions, both named and anonymous. However,this is not a function parameter or local variable—it’s a special JavaScript keyword— so these rules do not apply. By copying the value of this into a local variable, we take advantage of the closure to make that value available in any nested functions.


All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

J Query Topics