this
was the first JavaScript topic that really had me stumped. I couldn’t understand it no matter how hard I tried, and it was even more difficult trying to figure out how to use it. Don’t even get me started on .call()
, .bind()
, and .apply()
. That’s why I decided to tackle this
for my first coding blog post.
Let's be honest, context matters. Why? Because without context, we would never be able to make educated decisions, add insightful comments to a conversation, or simply, understand sarcasm. Context is what gives meaning to everything that we do in our daily lives. Context is everything. Context is king. And context is what you need to understand how to use this
.
Execution Context
Execution context is the abstract concept of an environment that the JavaScript engine sets aside to handle the transformation and execution of code. In JS, there are two types of execution context: Global Execution Context (GEC) and Function Execution Context (FEC). Embed these acronyms in your brain now, because we will be using them often.
To start, we need to understand that regardless of which context is being created, both undergo a two-phase creation process:
- The Creation Phase
- The Execution Phase
For GEC, the creation phase begins when an execution context is created but before the code runs. For FEC, the creation phase begins whenever the function is called. Something to keep in mind is that there can be more than one FEC, distinct to each function, but there can only be one GEC. In addition, the Function Execution Context can access the entire code of the Global Execution Context, but not the other way around. This is analogous to how a one-way mirror works, in that, the FEC can “see” externally towards the GEC, but the GEC cannot “see” internally towards the FEC.
Once the creation phase initiates, a variable object is created that stores the variables and function declarations within the execution context. This object is the Execution Context Object that we will refer to later.
After, the scope chain is formed. But what is the scope chain and how does it work? It’s all about positioning. We’ll use the analogy again, the one-way mirror. Code within nested functions can “see” externally towards the global scope, but the global scope cannot “see” into functions. We call this lexical scoping. When JavaScript resolves code, the engine will traverse up the scope chain to determine what additional variables and functions the code can access. Keep in mind that scope can not jump laterally, so to speak, so function A does not have the same scope as function B if they are not nested in any way.
Lastly, the value of this
is initialized by the JS engine. The keyword points to an object that the current code is being executed on. What is this object, you may wonder? For GEC and FEC, it is the Execution Context Object that was created at the beginning of the creation phase. This global object is also referred to as the window object
and represents an open window in a browser. Another important way this
can be utilized is in an object method. When used in a method, this
refers to the owner object.
Now that the creation phase is finished, the JS engine starts reading the code and executing it one line at a time. This phase involves assigning values to variables, executing functions and code blocks as it is encountered, and managing the call stack, a data structure that keeps track of functions currently being executed.
And voila, we have gone over the context needed to finally discuss how to use this
. A round of applause for everyone who’s made it this far.
this
Let’s start this out by reiterating that this
is a keyword that refers to an object based on how it is invoked. Within the GEC and FEC, this
refers to the window
.
And within an object method, this
refers to the object itself. How is this possible? We need to understand how object methods are created. Let's look at the following example:
Here I've written out a method for food
which prints a string containing fruit
's value. We can rewrite this 'shorthand'.
This shorthand syntax increases readability and saves time. Below, I've taken the code and applied this
.
Notice in all three of these scenarios, food.printFruit()
prints the same thing. So, let's circle back to the original question. How is it possible that, within an object method, this
refers to the object itself? It is possible because the moment we invoke the method on the adjacent object food
, this
is implicitly bound to food
. I suppose the whole idea is a bit circular but I hope that clears it up!
Now we know that this
is a keyword that refers to an object based on where and how it is invoked at the time it is invoked. this
is not a variable and we cannot change its value.
There's so much more to this
that I did not cover in this blog, such as how to use this
when it comes to methods: .call()
, .bind()
, and .apply()
. But that will have to be a post of its own. For now, we have answered the first question. What is this
?
Top comments (0)