‘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.
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
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.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
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.
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
functionAs you can see, when we call
printName
Normally this points to WindowAs 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
and how it may get changed in various scenarios.this
Hope you have learned something new today…
For further understanding please consider the below sources:
Feedback and suggestions are welcome.
Reach out to me on Twitter.
Until then...
Also published at https://medium.com/geekculture/understanding-this-in-javascript-22c068616f5a