Understanding the 5 rules around this keyword in JavaScript will make you a master of this topic.

"this" keyword in JavaScript is one of the most asked topics in the frontend interviews for the frontend devs with under 5 years of experience.
This is one of the tricky topics because "this" behaves differently depending on context, and that’s where most developers get tripped up—especially in interviews.
When you’re in the global scope, this usually points to the global object—that’s window in browsers. But in strict mode, it becomes undefined.
"use strict";
var name = "FrontendGeek";
let city = "Pune";
console.log(this.name); // "FrontendGeek"
console.log(this.city); // undefined (because `let` is not on window)
console.log(this === window); // false in strict mode👉 For a deeper dive into strict mode and how it changes things - MDN Strict Mode
When a function is called as part of an object, this points to that object. However, if you. Simply call it a plain function, which falls back to the global context.
const user = {
name: "Anuj",
greet() {
console.log(`Hello, I’m ${this.name}`);
}
};
user.greet(); // Hello, I’m Anuj
const greetFunc = user.greet;
greetFunc();
// Global context → undefined in strict mode
When you call a function with new, a fresh object is created, and this points to it.
function Person(name) {
this.name = name;
}
const bob = new Person("Anuj");
console.log(bob.name); // AnujEven if you don’t explicitly return an object, the new instance is returned by default. This is a foundational concept when building custom classes or components.
call, apply, bindSometimes you need fine control. That’s where call(), apply(), and bind() come in. They let you explicitly set the value of this.
function sayHello(greeting) {
console.log(`${greeting}, I’m ${this.name}`);
}
const user = { name: "Anuj" };
sayHello.call(user, "Hi"); // Hi, I’m Anuj
sayHello.apply(user, ["Hey"]); // Hey, I’m Anuj
const bound = sayHello.bind(user);
bound("Hello"); // Hello, I’m AnujCheckout the polyfills of call, apply and bind
thisArrow functions don’t have their own this. Instead, they inherit it from where they are defined (lexical scope).
const user = {
name: "Anuj",
regular: function() {
console.log("regular:", this.name);
},
arrow: () => {
console.log("arrow:", this.name);
},
withInner: function() {
return () => console.log("inner arrow:", this.name);
}
};
user.regular(); // regular: Anuj
user.arrow(); // arrow: undefined (arrow takes global `this`)
const inner = user.withInner();
inner(); // inner arrow: Anuj0
6
0