Pass correct "this" context to setTimeout callback?
Use an arrow function as a setTimeout callback to preserve the this
context:
Or, bind this
to a traditional function:
The "this" identity crisis
Dealing with the this
keyword in JavaScript often feels like dealing with identity theft - the thief being setTimeout
. A common gripe with setTimeout
is this
no longer refers to our expected context within the callback function, instead, it points to the global object. How rude!
Getting closure with closures
You can resolve this deceit by capturing, or holding hostage, the current this
value (a closure) and using it within setTimeout
like so:
Bind vs. Theft
Looking for compatibility with older browsers, like that grandpa Internet Explorer, we can use Function.prototype.bind
. This forces our function into a binding contract to uphold its this
identity, even under the nefarious tricks of setTimeout
:
Extra parameters, extra context
HTML5 added some new specs to setTimeout
allowing us to sneak in the real this
as an extra parameter amongst the innocuous delay period:
However, much like rainy holidays are part and parcel of life, this method could fail in older browsers. Always check the forecast - I mean, browser compatibility.
Libraries - the hired help
Libraries like jQuery and lodash provide methods to hold this
hostage ensuring it won't be impersonated during the setTimeout
heist. Actions like jQuery's $.proxy()
and lodash's _.bind()
could be useful additions to your code base.
Dealing with a narrow Window(IE)
Speaking of older versions of IE, they don't take too kindly to outsiders like bind
. In these cases, using a cloaking device (a closure, or a jQuery method) may be the only way out.
Performance hustle
There may be minor differences in performance between these methods. Although it won’t impact a setTimeout
context, it's worth noting closures could cause more memory usage compared to bind
or arrow functions due to that extra scope they create. It's like carrying a bit more baggage on a journey, but then, aren't we all?
Advanced Pitfalls
Implicit and Explicit binding
Oftentimes, we make mistakes by overriding the this
binding provided by bind
, .call()
, or .apply()
. Please remember, double-binding doesn't revert the this
context back to its original state. That's just not its style!
Arrow functions and lexical scope
While arrow functions are leashed to their surrounding context, remember they cannot be bound using bind
, call
, or apply
. They are more rebellious types and they love their freedom!
Compatibility with transpilers or polyfills
While using additional arguments with setTimeout
in modern JavaScript, remember that not all transpilers or polyfills may support these advanced techniques. They are sort of like musical purists who insist on vinyl records. So, always check your transpiled code!
Was this article helpful?