FrontendPrep
Menu
Topics
Questions
Guides
Challenges
Soon
Back to JavaScript Questions
javascriptMedium

Explain JavaScript 'this' Keyword with Interview Examples

Master the JavaScript this keyword for frontend interviews. Learn how this works in global scope, objects, functions, arrow functions, event handlers, classes, call, apply, and bind with practical examples.

Explain the JavaScript this Keyword

One of the most frequently asked JavaScript interview questions is:

What is this in JavaScript and how does it work?

Many developers memorize rules such as:

this === window;

or

arrow functions don't have this

but struggle when interviewers ask:

What determines the value of this?

The most important thing to understand is:

this is 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:

John

Here:

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:

John

Equivalent 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:

John

Interview 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:

undefined

Why?

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:

John

Arrow function:

const user = {
  name: "John",
 
  greet: () => {
    console.log(this.name);
  },
};

Output:

undefined

Common 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:

undefined

Why?

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:

John

Solution 2: Arrow Function

const user = {
  name: "John",
 
  greet() {
    const inner = () => {
      console.log(this.name);
    };
 
    inner();
  },
};

Output:

John

Arrow 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:

John

Explicit 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 Delhi

Explicit 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:

John

call vs apply vs bind

MethodExecutes ImmediatelyReturns Function
callYesNo
applyYesNo
bindNoYes

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:

John

Here:

this === user;

9. Common Interview Q&A

What Determines the Value of this?

Not where the function is written.

Instead:

How the function is called

determines 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 this in JavaScript is determined by how a function is invoked. In global scope, this usually refers to the global object. In object methods, it refers to the object before the dot. Constructor functions bind this to newly created instances via new. Functions can explicitly set this using call, apply, and bind. Arrow functions are different because they do not have their own this; instead they inherit it lexically from the surrounding scope. Understanding invocation patterns rather than memorizing rules is the key to mastering this.

Key Takeaways

  • Dynamic Binding: The value of this is determined dynamically at runtime based on how a function is called, not where it is written.
  • Global Context: Points to window (or global in Node.js), resolving to undefined inside 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(), or bind() to explicitly force a specific context object onto this.
  • Event Listeners: Inside event callbacks, this naturally points to the DOM element that received the event.

Share this Resource

Help other developers level up by sharing this study guide.

More Technical Questions

Expand your mastery. Deep dive into other frontend interview challenges in this category.