Explain the JavaScript this Keyword
One of the most frequently asked JavaScript interview questions is:
What is
thisin JavaScript and how does it work?
Many developers memorize rules such as:
this === window;or
arrow functions don't have thisbut struggle when interviewers ask:
What determines the value of
this?
The most important thing to understand is:
thisis determined by how a function is called, not where it is defined.
What is this?
this is a special keyword that refers to an object associated with the current execution context.
The value of this is decided at runtime.
Example:
const user = {
name: "John",
greet() {
console.log(this.name);
},
};
user.greet();Output:
JohnHere:
this === user;because the function was called using:
user.greet();Why Does JavaScript Need this?
Imagine creating multiple objects:
const user1 = {
name: "John",
};
const user2 = {
name: "Sarah",
};Without this, every method would need hardcoded references.
const user = {
name: "John",
greet() {
console.log(user.name);
},
};This breaks when reused.
With this:
const user = {
name: "John",
greet() {
console.log(this.name);
},
};The method becomes reusable for different objects.
3. Global Context & Function Invocation Rules
In browsers:
console.log(this);Output:
window;Because the global execution context is the browser window.
Browser Example
var name = "John";
console.log(this.name);Output:
JohnEquivalent to:
window.name;Rule #2: Function Invocation
Consider:
function greet() {
console.log(this);
}
greet();In non-strict mode:
window;In strict mode:
undefined;Strict Mode Example
"use strict";
function greet() {
console.log(this);
}
greet();Output:
undefined;This prevents accidental global object access.
4. Method Invocation Rule
When a function is called as an object's method:
object.method();this refers to that object.
Example:
const user = {
name: "John",
greet() {
console.log(this.name);
},
};
user.greet();Output:
JohnInterview Trap
const user = {
name: "John",
greet() {
console.log(this.name);
},
};
const fn = user.greet;
fn();Output:
undefined(or window.name in non-strict mode)
Why?
Because:
fn();is a normal function call.
The connection to user is lost.
5. Constructor Functions Rule
When using new:
function User(name) {
this.name = name;
}
const user = new User("John");JavaScript creates a new object and binds this to it.
Equivalent to:
const user = {};
user.name = "John";Output:
{
name: "John";
}6. Arrow Functions & Lexical Binding
Arrow functions do NOT create their own this.
Instead, they inherit this from the surrounding scope.
Example:
const user = {
name: "John",
greet: () => {
console.log(this.name);
},
};
user.greet();Output:
undefinedWhy?
Because the arrow function uses the surrounding this.
It does not receive:
this === user;Normal Function vs Arrow Function
Normal function:
const user = {
name: "John",
greet() {
console.log(this.name);
},
};Output:
JohnArrow function:
const user = {
name: "John",
greet: () => {
console.log(this.name);
},
};Output:
undefinedCommon React Example
Bad:
class App {
handleClick() {
console.log(this);
}
}Passing directly:
<button onClick={this.handleClick}>may lose context.
Historically developers used:
this.handleClick = this.handleClick.bind(this);inside constructors.
Nested Functions Problem
const user = {
name: "John",
greet() {
function inner() {
console.log(this.name);
}
inner();
},
};
user.greet();Output:
undefinedWhy?
Because:
inner();is a normal function call.
Solution 1: Store Reference
const user = {
name: "John",
greet() {
const self = this;
function inner() {
console.log(self.name);
}
inner();
},
};Output:
JohnSolution 2: Arrow Function
const user = {
name: "John",
greet() {
const inner = () => {
console.log(this.name);
};
inner();
},
};Output:
JohnArrow functions inherit the surrounding this.
7. Explicit Binding: call(), apply(), and bind()
call() immediately invokes a function and sets this.
function greet() {
console.log(this.name);
}
const user = {
name: "John",
};
greet.call(user);Output:
JohnExplicit Binding with apply()
Works like call() but arguments are passed as an array.
function greet(city) {
console.log(this.name, city);
}
const user = {
name: "John",
};
greet.apply(user, ["Delhi"]);Output:
John DelhiExplicit Binding with bind()
Unlike call and apply:
bind();does NOT execute immediately.
It returns a new function.
function greet() {
console.log(this.name);
}
const user = {
name: "John",
};
const boundFn = greet.bind(user);
boundFn();Output:
Johncall vs apply vs bind
| Method | Executes Immediately | Returns Function |
|---|---|---|
| call | Yes | No |
| apply | Yes | No |
| bind | No | Yes |
8. 'this' inside Event Handlers & Classes
button.addEventListener("click", function () {
console.log(this);
});Output:
<button>Inside event listeners:
this === element;Event Handler with Arrow Function
button.addEventListener("click", () => {
console.log(this);
});Output:
window;(or outer scope)
Arrow functions do not get event-bound this.
Classes and this
class User {
constructor(name) {
this.name = name;
}
greet() {
console.log(this.name);
}
}
const user = new User("John");
user.greet();Output:
JohnHere:
this === user;9. Common Interview Q&A
What Determines the Value of this?
Not where the function is written.
Instead:
How the function is calleddetermines this.
Do Arrow Functions Have Their Own this?
No.
They inherit this from the surrounding lexical scope.
Why Is bind() Useful?
It permanently fixes the value of this.
const fn = greet.bind(user);Useful when passing methods as callbacks.
Why Does React Use Arrow Functions Frequently?
Arrow functions preserve lexical this.
This avoids losing context when functions are passed around.
Senior-Level Interview Answer
The value of
thisin JavaScript is determined by how a function is invoked. In global scope,thisusually refers to the global object. In object methods, it refers to the object before the dot. Constructor functions bindthisto newly created instances vianew. Functions can explicitly setthisusing call, apply, and bind. Arrow functions are different because they do not have their ownthis; instead they inherit it lexically from the surrounding scope. Understanding invocation patterns rather than memorizing rules is the key to masteringthis.
Key Takeaways
- Dynamic Binding: The value of
thisis determined dynamically at runtime based on how a function is called, not where it is written. - Global Context: Points to
window(orglobalin Node.js), resolving toundefinedinside strict-mode execution. - Arrow Functions: Do not bind their own
this; they inherit it lexically from their surrounding declaration context. - Explicit Binding: Use
call(),apply(), orbind()to explicitly force a specific context object ontothis. - Event Listeners: Inside event callbacks,
thisnaturally points to the DOM element that received the event.