Understand Javascript this keyword in 5 easy steps
Javascript is a very popular programming language. It is a go-to programming language for most beginners. But going deeper, you realize that it has some weird concepts which can be frustrating for most beginners. I have had my share of frustrations and that’s why I have put this article together. In this article, we will break down ‘this’ keyword in Javascript in 5 easy steps. At the end of this article, you should be conversant with ‘this’ object and conveniently use it in your code.
Before we proceed, I would make this clear first. I would assume that you are familiar with Javascript Functions and at least basic knowledge of OOP in Javascript. You can read JavaScript Functions Made Easy: Streamlining Code for Beginners! on functions and Classes in Javascript on Javascript Classes. Also, you will need to follow along with the coding part. Just reading through the article will not help you much.
Introduction to ‘this’ keyword
‘this’ is used for a person, object, or thing to show which one is referred to by way of emphasis. For example, you could say “This is my laptop, yours is over there”. In this sentence, you referred to your laptop using ‘this’ to emphasize which of the two laptop is yours. Similarly, you use the ‘this’ keyword to refer to a specific, or even better, the current object in Javascript. The object that is referred to will depend on the context or ‘environment’ where your code runs. Whatever the context, you would use ‘this’ to refer to that context.
Take note that the value of ‘this’ object depends on how a function is invoked and not how a function is defined. Understanding the code execution context is very crucial to knowing what to expect when you use the ‘this’ keyword.
Javascript Execution Context
Simply put, the execution context is the environment in which code is executed. Each context comes with its settings such as the variable scope, the ‘this’ keyword, and the rules that determine how the code behaves. We will not discuss the execution context in detail. Just think of it as the wrapper that manages your code. However, I will explain some concepts in which the ‘this’ keyword can be invoked i.e. the regular function context, arrow function context, and class context.
Before I go into explaining these 3 contexts, let's take a look at the Global Context. The global context is represented by the ‘window’ object. This ‘window’ object is automatically created by the browser when a web page is loaded. It represents the browser window or the global environment in which the code runs within the page. Imagine the ‘window’ object as your external javascript file or the inline code between the <script></script>
, except code that is in blocks or functions.
Let’s consider this line of code in the global context of a browser as illustrated below;
//Global execution context
console.log(window === window); //true in a web browser
We compare the ‘window’ object to itself which obviously will be true.
Now let's check if ‘this’ is the same as the ‘window’ object’;
//Global execution context
console.log(this === window); //true in a web browser
We get true as well. Therefore we can refer to the ‘window’ object with ‘this’ and get all the properties and methods that the ‘window’ object holds.
Let's take another example. Do you know the alert()
function? It’s a method of the window object. Run the following code;
window.alert('hello');
which is equivalent to
this.alert('hello');
You can also create your methods and properties in the ‘window’ object. Create variables or functions without using the variable declaration keyword to make global variables and methods.
However, when you are in the ‘strict mode’, ‘this’ will result in ‘undefined’ if not bound explicitly. This is used to detect potential bugs and encourage developers to be more explicit about their code’s behavior.
Understanding ‘this’ in regular function
A regular function is a function that is defined using the function keyword followed by the function name, list of parameters separated by commas, and enclosed in parenthesis with the code that defines the function, enclosed inside curly braces as shown below;
function name(parameter){
//Your function's code goes here
}
Each function creates its own scope and context. This means it encapsulates variables within its scope and defines its own context through the ‘this’ keyword. The value of the ‘this’ keyword depends on how the function is invoked.
- When a regular function is invoked in the global context, ‘this’ refers to the global object which is the window object.
function greet(){
console.log(this);
}
greet(); // window {...}
- If the function is invoked using the new constructor keyword, a new empty object is created and ‘this’ will refer to that empty object;
function Greet(){
console.log(this);
}
let Hello = new Greet();
Hello //greet{}
Now let's modify our code;
function Greet(){
let message = 'Hello there';
console.log(this);
}
let Hello = new Greet();
Hello // Greet{}
We are not getting the message variable as a property to the newly created Greet{} object because the message variable was not declared as a property of ‘this’ object.
Let’s add the message variable to the ‘this’ object;
function Greet(){
this.message = 'Hello there';
console.log(this);
}
let Hello = new Greet();
Hello // Greet {message: 'Hello there'}
We can also use the bind() method to set the context for our
function;
//create the function
function person(){
console.log(this.name);
}
// use bind to set context
var obj = {
name: 'John Smith',
}
var newPerson = person.bind(obj)
// bind() method returns a new function with the context set to obj
newPerson(); // John Smith
Hence with regular functions, you can either use the new constructor keyword or the bind method to set the context of the function.
Arrow function and ‘this’ object
Arrow functions in JavaScript do not have their own ‘this’ context. Instead, they inherit the 'this’ value from the enclosing lexical or outer context. This behavior can sometimes be an advantage, especially in scenarios where you want to maintain the context of ‘this’ within nested functions.
Consider the code below;
const obj = {
name: "John Smith",
greet: function() {
console.log(`Hello, my name is ${this.name}`);
},
greetArrow: () => {
console.log(`Hello, my name is ${this.name}`); // 'this' here refers to the outer context
}
};
obj.greet(); // Output: Hello, my name is John
obj.greetArrow(); // Output: Hello, my name is undefined
The name value is undefined because there is no name property for the global context. To correct this, we add the name to the outer scope;
this.name = 'John Doe' //name property in the outer context
const obj = {
name: "John Smith",
greet: function() {
console.log(`Hello, my name is ${this.name}`);
},
greetArrow: () => {
console.log(`Hello, my name is ${this.name}`); // 'this' here refers to the outer context
}
};
obj.greet(); // Output: Hello, my name is John
obj.greetArrow(); // Output: Hello, my name is John Doe
However, using ‘this’ in the arrow function can be a pitfall if you rely on dynamic ‘this’ binding, especially in event handlers or prototype methods.
‘this’ in Class context
Classes are blueprints or templates for creating objects. you specify the properties (data) and methods (behavior) that each object created from the class will have. If you need a new object, you just create it using the new constructor keyword.
The ‘this’ keyword behaves differently in class contexts such as;
- When used inside the constructor method, ‘this’ refers to the newly created instance of the class. It allows you to set properties on the object during initialization.
class Person{
constructor(name){
this.name = name;
}
}
let sarah = new Person('Sarah');
console.log(sarah.name) // Sarah
- Functions in a class are called methods. When methods are invoked, the ‘this’ references the new instance of the class on which the method is called. It allows methods to access and manipulate the properties of the object.
class Person{
constructor(name){
this.name = name;
}
greet(){
return `Hi, they call me ${this.name}`;
}
}
let sarah = new Person('Sarah');
console.log(sarah.greet()) // Hi, they call me Sarah
- When a static method is called, it is invoked directly on the class itself, rather than on an instance of the class. Therefore, ‘this’ within a static method does not refer to an instance of the class; instead, it refers to the class itself.
class Person{
static introduce(){
return `Welcome to Person class`;
}
}
console.log(Person.introduce());
Conclusion
In summary, ‘this’ allows you to dynamically refer to different objects depending on how functions are called or where they are defined, providing flexibility and context-aware behavior in your code.
Subscribe to my newsletter
Read articles from Anwar Sadat Ayub directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Anwar Sadat Ayub
Anwar Sadat Ayub
I love to build robust software solutions to make life easy. In a similar way, I write articles to explain complex technical concepts. I simply want to make technology accessible and understandable for everyone.