Is "this" tricky in Javascript? No way!๐
Understanding the "this" keyword in JavaScript: Explained with Examples
In JavaScript, the this
keyword is a special identifier that refers to the context in which a function is executed. It plays a crucial role in determining how functions behave and which object they belong to. However, the behaviour of this
can be confusing for many developers.
Simply, this
points to the context in which it is used. We will explore various examples of this
keyword and understand how it points to the context in which it is used. We will also see examples where this
can be explicitly bound to any specific object or a function call.
Global Context: Default Binding
When this
is used outside of any function, it refers to the global object. In a web browser environment, the global object is usually the window
object. Let's consider the following example:
console.log(this); // Output: Window
In this case, this
points to the window
object because the code is executed in the global context. Pointing to the window object specifies that this
will have access to all the properties of the window object. For example, as window
object has setTimeout
property, so here we can access it through this.setTimeout
as well. It is that simple!
Object Method: Implicit Binding
When a function is called as a method of an object, this
refers to the object itself. This behavior is known as implicit binding. It's called Implicit because it is assigned by the javascript engine during the runtime. Let's look at an example:
const person = {
name: 'Om',
greet: function() {
console.log(`Hello, my name is ${this.name}.`);
}
};
person.greet(); // Output: Hello, my name is Om.
In this example, this
inside the greet()
method refers to the person
object. It allows us to access the name
property of the person
object using this.name
. Here, this
will only have access to the properties defined in the person
object.
Event Handlers: DOM Binding
When an event handler is invoked, this
refers to the element that triggered the event. Let's consider an HTML button element with an event handler function:
<button onclick="console.log(this)">Click me</button>
In this case, when the button is clicked, this
inside the event handler function refers to the button element itself. It provides access to the element's properties and methods.
Constructor Functions: New Binding
When a function is used as a constructor with the new
keyword, this
refers to the newly created object. Constructor functions are used to create multiple objects with the same properties and methods. Here's an example:
function Person(name) {
this.name = name;
}
// can also be defined with class keyword
/*
class Person {
constructor(name) {
this.name = name;
}
}*/
const person = new Person('Om');
console.log(person.name); // Output: Om
In this example, the Person
function acts as a constructor to create a new Person
object. Inside the constructor, this
refers to the newly created object (john
), allowing us to set the name
property.
Explicit Binding: Call, Apply, and Bind
JavaScript provides three methods - call()
, apply()
, and bind()
- that allows us to explicitly specify the value of this
within a function. Let's explore each of them with an example:
Note - To understand these functions in detail you can check here.
function greet() {
console.log(`Hello, ${this.name}!`);
}
const person1 = { name: 'Om' };
const person2 = { name: 'Apurva' };
greet.call(person1); // Output: Hello, Om!
greet.call(person2); // Output: Hello, Apurva!
greet.apply(person1); // Output: Hello, Om!
greet.apply(person2); // Output: Hello, Apurva!
const greetPerson1 = greet.bind(person1);
const greetPerson2 = greet.bind(person2);
greetPerson1(); // Output: Hello, Om!
greetPerson2(); // Output: Hello, Apurva!
In the above example, we define a greet()
function that logs a greeting message. By using call()
, apply()
, and bind()
, we explicitly set this
to the person
object. This allows us to access the name
property of person
within the greet()
function.
Arrow Functions: Lexical Binding
Arrow functions do not bind their own this
value. Instead, they inherit the this
value from the enclosing context.
const person = {
name: "Om",
greet: function() {
setTimeout(() => {
console.log(`Hello, my name is ${this.name}`);
}, 1000);
}
};
person.greet(); // Output: Hello, my name is Om
Here the callback function (an arrow function) in setTimeout
will refer to the context of the object method greet. As we know the object method will refer to the person
object in which it is defined (this we have already seen in the Object Method section), and the callback will also refer to person
object.
These examples demonstrate how the context of this
can vary depending on the way a function is called or the surrounding code. Understanding the different contexts of this
is crucial for writing correct and maintainable JavaScript code.