JavaScript, known as the language of the web, is a lightweight, interpreted programming language used to add interactivity to web pages, applications, and servers. As the language of the web, JavaScript is one of the most popular programming languages used in development. It has various web frameworks that help ease development and enhance productivity.
To make the best use of JavaScript, developers must understand its syntax and semantics, and more importantly, how to properly apply them in development. The this keyword in JavaScript has been a source of confusion among developers, especially developers learning JavaScript for the first time.
In this blog post, we will learn about this in JavaScript, how to properly use it, and where to use it.
What is this in JavaScript?
The JavaScript this keyword refers to an object where a piece of code is supposed to run. It is mostly used in object methods, where this refers to the method that executes the current function. When an object is referenced using this, the value returned depends on how and where the object is being called, not necessarily what has been defined in the object.
We can further explain this using the ‘this’ pronoun in English. Consider this statement: “There are three balls in the box, but this one is the biggest”. Now, without an action from the speaker, we cannot know which of the balls is the biggest. If the speaker makes the statement, and then points at or picks up a ball, then we can determine which of the balls is being referred to. Similarly, the manner (action) and execution context in which an object is called will determine the value that will be returned.
Global Execution Context
We already established that the execution context where this is used will determine the value. A global execution context refers to an environment where code is executed that is not confined by any function, method, or block. Variables defined in the global execution context can be accessed from any part of the codebase.
In the browser, the global execution context is defined using the window object. All variables and functions defined globally automatically belong to the window object. We can then access the variables defined using the object. Let’s consider an example:
var bestAITool = "Pieces for Developers"; // defined globally |
Here, we defined the variable bestAITool globally and then referenced it using the JavaScript window object. Similarly, any variable declared globally can be accessed using this. Consider this example:
var bestAITool = "Pieces for Developers"; // defined globally |
In the above code snippet, we can see that the output remains the same when we replace the window keyword with this. This is because variables declared globally are automatically attached to the window object. Note that this applies to the browser only.
In the Node environment, the global object is accessed using the global keyword, an attempt to access a variable in Node using this in JavaScript will output an empty object. Consider the example below:
global bestAITool = "Pieces for Developers"; |
Here, we see that when we use this to access a global variable in a Node environment, it does not give the expected output.
Function Execution Context
The function execution context refers to the environment where a function is called or invoked. There are 4 ways a JavaScript function can be invoked which determines how this behaves. Let’s explore these 4 ways.
Function Invocation
When a function is invoked as a function in non-strict mode, this keyword references the window object (if it’s in the browser) or the global object (in a Node environment). In strict mode, this is set to undefined. Consider the example below:
function testFunction() { |
The testFunction function in the code snippet above outputs the window object.
Method Invocation
When a function is invoked as a method, the this JavaScript keyword refers to the particular object that owns the method. Consider the example below:
let bestCopilot = { |
In the above code snippet, action is the method of the bestCopilot object. When the bestCopilot.action method is called, this refers to the bestCopilot object (because the method is in that object).
Constructor Invocation
Constructor invocation entails calling a function by using the new keyword. To invoke a function as a constructor, it is preceded with the new keyword. The new keyword creates an instance of the function. When a function is invoked as a constructor, the following actions take place:
A new empty object is created.
this now refers to the newly created object.
The value of new becomes the newly constructed object.
Consider the code snippet below:
function Pieces(feature, purpose) { |
In the code snippet above, when new Pieces("code management feature", "save, search and extract snippets"); is invoked, a new object is created. The value of this now points to the newly created object. The properties are also assigned to the object. So, this.company now refers to the newly created company property, and this.tool refers to the newly created tool property. The output now becomes “With the Pieces Copilot feature, get a contextual answer based on your codebase”, instead of “With the Pieces code management feature, you can save, search, and extract snippets”.
Indirect Invocation
Indirect invocation entails manually setting the values of this using the call, apply, or bind JavaScript methods. These methods allow you to invoke any function as a method of any object. Let’s explore these methods:
- call(): The call() method allows you to explicitly specify the value of this while it invokes the function. It uses a list of arguments as arguments to the function. Consider the example below:
function announcement(feature) { |
Here, we explicitly set the value of this using the call() method. The company object was defined and “open source” was passed as the argument. So this now refers to the values set by the call method. The output is “Pieces OS is open-source”.
- apply(): The apply() method is similar to the call() method but uses an array of values as arguments. Let’s see how it works:
function announcement(feature) { |
Here’s our previous code snippet but with some slight changes, the method used here is the apply method so the argument was changed to an array type.
- bind(): The bind() method creates a new function that sets the value of the function to the provided value when it is called. It creates a new bound function. Consider the code below:
const company = { name: "Pieces" }; |
In the example above, we create a new function boundHello with the bind() method which sets this to the company object (provided value).
Arrow Functions
Arrow functions primarily do not have this in their execution context. It can, however, be set lexically. That is, this in JS uses the value of its surrounding lexical context. The value of this in an arrow function inherits the value of this in the closest non-arrow function. Consider the example below:
const company = { |
Here, we see that the arrowHello
arrow function does not have its own this defined in it but it inherits this from the sayHello method, where this refers to the company object.
Understanding the this JavaScript Keyword with Pieces
Got a solid knowledge of the JS this keyword and can’t wait to explore it in development? The this keyword can be tricky, especially in a large codebase where this is being used in different execution contexts. Let’s see how it works:
In the demo above, I have a piece of code that uses the this JavaScript keyword. To be extra sure, I asked Pieces Copilot “How is this being used in this context” and it gives a complete breakdown of how it is being used in my codebase. Pieces Copilot helps you navigate using this with an extra bit of confidence by providing contextual solutions specifically for your codebase. The good news is that you can also learn and confidently use other JavaScript concepts with Pieces Copilot as your companion. See also how you can learn C# with the help of Pieces.
Ready to get started? Download the Pieces Desktop Application and then proceed to use the Pieces extensions available on your favorite IDEs.
Conclusion
In this blog post, you have learned about this in JavaScript, how to use the this keyword, its global and function execution contexts, how different function invocation styles affect the behavior of the this keyword, and how you can confidently use the this keyword with the help of Pieces Copilot. Happy coding!