What is 'this’ in JavaScript?

Written by suhas010 | Published 2021/05/04
Tech Story Tags: javascript | reactjs | web-development | frontend-development | javascript-fundamentals | development | javascript-development | understanding-javascript

TLDR 'this' is always been a pain in the a** for many JavaScript developers, but it’s time to say ‘I got this’ Previously, I wrote Understanding Scope and Context in JavaScript. JavaScript will create a separate execution context for a function called with a new keyword. The value of this is determined by how a function is being called. JavaScript has introduced a new property called globalThis which points to global this or global this. In a web browser, the value of global this is different in NodeJS (Object), and in WebWorker it might be DedicatedWorkerGlobalScope.via the TL;DR App

this’ is always been a pain in the a** for many JavaScript developers, but it’s time to say ‘I got this
Previously, I wrote Understanding Scope and Context in JavaScript. Before reading this article, I recommend you read that article first, but if you think you have a good grasp on scope and context in JavaScript let’s continue.

So What is 'this’ in JavaScript?

The value of
this
keyword in a global context refers to a global object which is 
Window
in case of browser.
So answer to "what is 
this
 in JavaScript" is simple.
this
 contains a value that is most of the time is an object which is an execution context at that particular time.
As you can see in the above example, by default, 
this
 will contain an object the value that refers to the global execution context which is
Window
 in web browsers.
The value of
this
 is determined by how a function is being called.
if a function is called with a new keyword JavaScript will create a separate execution context for it.
Note: The value of this will change if we run it in strict mode.
As you can see in the above example, if 
constructorFunction
 called normally, this will now contain 
undefined
 value since it is running in strict mode.
JavaScript has introduced a new property called
globalThis
 which points to global 
this
 value.
Note: The value of global this is different in NodeJS (Object), and in WebWorker it might be DedicatedWorkerGlobalScope or SharedWorkerGlobalScope but in a web browser, it will be Window.
So all in all, this is nothing but the execution context in which that particular line of code is running, which is defined at runtime bindings
And as you can see, almost in all scenarios this is nothing but an object,
we sometimes call it context or execution context

How the value of 'this' is determined

We have understood what is 
this
 and what it contains, it’s time to learn some rules which identify the value of this at any given point in time.
Determining the value of 
this
 is the HARD part for many, which makes
this
 controversial in JavaScript.
We’ll list down all possible scenarios where 
this
 value gets changed.

Default value

This is the most simple part, open up devtools and log 
this
 , it will look like this in Chrome.
As you can see, all are logging the same value which is a Window object.
This is the default execution context in JavaScript, every function by default gets executed in the default context.
A variable declared in the global scope (using var) gets added in the 
Window
 object and we can access them using 
window.varName

Changing the value of this

If this will always point to the Window object, we can not achieve code reusability, code abstraction and we will pollute the global context.
That's why there is a way using which we can create custom context and change the execution context of some function that is already defined in some other context.

Callapply, and bind to rescue us.

These are the methods available on the Function prototype, and the purpose of all three methods is the same it’s just that there is deference in implementation.
We are not going to look at these methods in detail but will explain in short with some examples.
Let’s imagine, you wrote a function called 
printName
 that accepts messages as input and prints a variable called
name
to the console from the context in which it is running.
All good, right, In the above example, we created a variable called name which will get added on the window object, and since 
printName
 function by default runs in global context variable name is available on 
this
.
Now imagine, there is a change in requirements and now you have another object called user who also contains a property called name and you want to print it on the console.
Since you are a good programmer and you practice DRY, you want to reuse the above function which does the job.
As you can see above, we are now able to print property called
name 
which is available in user object and not in the Window object.
Basically, we are changing the context of the original 
printName
 function which by default runs in the global context.
And 
call
apply
 and 
bind
 method saying,
printName
 please run-in
user
 context,
Have a close look at the below example, Now we are also logging 
this
 in
printName
 function
As you can see, when we call 
printName
 Normally this points to Window
and when we call using call, apply, and bind this is pointing to the User object.

Normal function vs arrow(fat) function

As you can see in the above example, we created an object called
customeScope
 and defined an anonymous function and assigned it to a property called 
printName
 which prints 
this
 and 
name
 property. The second example is identical to the first only difference is that we are using the arrow function.
But this small difference results in a big change.
Explanation:
arrow(=>) function by default does not have this set to Window which is in normal function. Rather an arrow function executes in scope they are created.
In the above snippet, in the first example, this is pointing to a context in which they are created which is customeScope.
In the second example, since the arrow function do not have it’s own 
this
, it will use
this
 value of enclosing scope, which is Window (enclosing scope is 
customeScope
 whose 
this
 is Window).
Arrow function example
That's all for today, I have tried my best to explain what is 
this
 and how it may get changed in various scenarios.
Hope you have learned something new today…
For further understanding please consider the below sources:
  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide
  2. https://javascript.info/
Feedback and suggestions are welcome.
Reach out to me on Twitter.
Until then...

Written by suhas010 | JavaScript enthusiastic, in love with ReactJS
Published by HackerNoon on 2021/05/04