Reincarnated ‘this’ keyword in Javascript
Recently in one of my React projects, I stumbled upon a weird error where the variable expected to be printed was actually printed as undefined
. Ehhh… this doesn’t sound new right !!!
Let me explain you with an example:
This works perfectly fine and gives the output as:
cars.message();
"bmw has several models."
Now let’s tweak the above example a little bit and let’s observe the output:
Looks pretty well yeah… Let’s run the above code snippet and see what’s the output:
cars.message();
["undefined has models of Q seris."]
Pretty confused huh !!! This is because this
is referring to the function that called it which doesn’t know what brand
is. In our case, it’s the message
function that has no knowledge of what brand
is. Hence, this
needs to refer to the cars
object to get it back working.
We can achieve it in several ways like binding the this
keyword to the function, by giving cars
as an argument to the ‘callee’ function, etc. Let’s implement the later one and make sure it’s working fine:
This will give us output as below:
cars.message();
["bmw has models of Q seris."]
Back in business huh !!! Let’s make it simpler with the ES6 ‘fat arrow’ functions and compare both the solutions:
Which will give an output as below:
cars.message();
["bmw has models of Q seris."]
Notice how we have removed the function keyword inside the map
function and used just an arrow followed by a code block. This is the syntax of the ES6 Arrow Function.
Arrow functions don’t have their own ‘this’ which means that inside an arrow function, this
refer to the values of this
in the environment, the arrow function is defined in (i.e. "outside" the arrow function). This is called as ‘lexical scoping’. In our case, this
refers to this
of cars
object itself.
The benefit of using arrow functions is that it reduces the confusion surrounding the this
keyword. In code with multiple nested functions, it can be difficult to keep track of and remember to bind the correct this context. In ES5, we can use workarounds like the .bind method (which is slow) or creating a closure using var self = this;
as discussed above.
Thanks for being with me throughout this article and believe me 10 cups of coffee made it a little bit easy to understand !!!
If you liked this article, share it, tweet it !