"this" keyword in JavaScript
Every function while executing has a reference to its current execution context called this. In other words: in JavaScript, whenever a function executes, it contains a this keyword in its execution context. The this keyword refers to an object.
There are six rules for determining the value of this in JavaScript:
- Default Binding
- Implicit Binding
thisKeyword Inside Arrow Functions- Explicit Binding (Using
callandapply) - Hard Binding (Using
bind) - New Keyword
This chapter covers the first two — default binding and implicit binding. The remaining four are covered in upcoming chapters.
Default Binding
obj.user.getName()In the expression obj.user.getName(), obj.user is referred to as the "call site," and getName is a function. Within the getName function, the value of this is obj.user.
user.getName()In this expression, user is referred to as the "call site," and getName is a function. Inside the getName function, the value of this is the user object.
getName()In this case, there is no specific call site indicated. As a result, the value of this points to the global object, which is typically the window object in a browser environment.
Example 1
var name = "Deepak";
function displayName() {
console.log(this.name);
}
displayName(); // "Deepak"In this example, there is no specific call site indicated for the displayName function. Therefore, the value of this defaults to the global object. Consequently, it displays "Deepak" because name is defined in the global scope.
Example 2
function displayName() {
console.log(this.name);
}
displayName(); // undefinedIn this example, there is no specific call site indicated for the displayName function. Therefore, the value of this defaults to the global object. It displays undefined because the name property is not defined in the global scope.
This scenario, where there is no explicit call site during a function call, is referred to as default binding.
Implicit Binding
Consider the following program:
function displayName() {
console.log(this.name);
}
var obj1 = { name: "Deepak", displayName };
var obj2 = { name: "Mayur", displayName };
obj1.displayName();
obj2.displayName();In this example, when we invoke obj1.displayName(), the value of this inside the displayName function is obj1 because the call site is obj1. Consequently, the displayName function effectively becomes:
function displayName() {
console.log(obj1.name); // Deepak
}Similarly, when calling obj2.displayName(), the value of this is obj2, and the displayName function becomes:
function displayName() {
console.log(obj2.name); // Mayur
}This scenario, where this is implicitly determined by the call site during a function call, is referred to as implicit binding.
Questions
The questions below assume a classic, non-strict script context — the same one the rest of the chapter uses. In strict mode (and ES modules, which are strict by default), the bare-function calls in Q1, Q2, Q4, Q5, and Q6 would see
thisasundefined, and several of these would throwTypeErrorinstead of loggingundefined.
1. What is the console output of this program?
console.log(this === window);Answer — true
Explanation: In the global context, this refers to the window object by default.
2. What is the console output of this program?
this.color = 'Red';
console.log(window.color);Answer — Red
3. What is the value of this inside the next function?
let counter = {
count: 0,
next: function () {
return this.count + 1;
},
};
counter.next();Answer — 1
Explanation: The value of this inside the next function is the counter object. When counter.next() is called, it returns the value of this.count + 1, which is 1.
4. What will this program log?
let car = {
brand: 'Honda',
getBrand: function () {
return this.brand;
}
};
const brand = car.getBrand;
console.log(brand());Answer — undefined
Explanation: When brand() is called, there is no specified context (call site), so this refers to the global object (window in a browser). Since brand is not defined in the global scope, it results in undefined.
5. What is the output of the following program?
function userDetails() {
console.log(this.name);
function userCity() {
console.log(this.city);
}
userCity();
}
userDetails();Answer:
undefined
undefined
Explanation: When userDetails() is called, this inside userDetails refers to the global object (usually window in a browser). However, neither name nor city is defined in the global scope, so they both result in undefined.
6. What is the output of the following program?
const person = {
name: "John",
skills: ["HTML", "CSS", "JS"],
logSkills: function () {
this.skills.forEach(function log(skill) {
console.log(`${this.name} can do ${skill}.`);
});
}
};
person.logSkills();Answer:
undefined can do HTML.
undefined can do CSS.
undefined can do JS.
Explanation: Inside the logSkills method, when the forEach loop iterates, the value of this inside the inner function becomes the global object (window in a browser). Therefore, this.name is undefined.