JavaScript 'this' Explained: call/apply/bind + Arrow Functions

A practical guide to 'this' in JavaScript: default binding, implicit binding, explicit binding (call/apply/bind), new binding, and how arrow functions change it.

F

Frontend Interview Team

February 08, 2026

~14 min
JavaScript 'this' Explained: call/apply/bind + Arrow Functions

this is confusing because it’s not lexical (in normal functions).

Meaning: this is usually decided by how a function is called, not where it’s written.

30‑second interview answer

In JavaScript, this in a normal function is determined by the call-site: default binding (undefined in strict mode), implicit binding (obj.method()), explicit binding (call/apply/bind), or new. Arrow functions don’t have their own this; they capture this from the surrounding lexical scope.

Key points

  • Normal functions: this = call-site.
  • Arrow functions: this = lexical.
  • bind returns a new function with fixed this.
  • Losing the call-site (const fn = obj.method) is a common bug.

The 4 rules (memorize these)

Rule 1: Default binding

function show() {
  console.log(this);
}
 
show();
  • In strict mode: this is undefined
  • In non-strict (browser): this is window

In modern code, assume strict mode.


Rule 2: Implicit binding (object method call)

const user = {
  name: 'Rajesh',
  show() {
    console.log(this.name);
  },
};
 
user.show(); // Rajesh

Here this is the object before the dot: user.

Common trap:

const fn = user.show;
fn(); // undefined (or error)

Because the call-site is now just fn() (default binding).


Rule 3: Explicit binding (call / apply / bind)

function greet(city) {
  return `Hi ${this.name} from ${city}`;
}
 
const person = { name: 'Rajesh' };
 
greet.call(person, 'Kharar');
// call: args passed one by one
 
greet.apply(person, ['Kharar']);
// apply: args passed as an array
 
const bound = greet.bind(person);
bound('Kharar');
// bind: returns a new function with this fixed

Interview tip:

  • call and apply invoke immediately.
  • bind returns a new function.

Rule 4: new binding

function Person(name) {
  this.name = name;
}
 
const p = new Person('Rajesh');
console.log(p.name); // Rajesh

When you use new, this points to the newly created object.


Arrow functions: the exception

Arrow functions don’t have their own this. They capture this from the surrounding scope (lexical this).

const user = {
  name: 'Rajesh',
  normal() {
    setTimeout(function () {
      console.log(this.name);
    }, 0);
  },
  arrow() {
    setTimeout(() => {
      console.log(this.name);
    }, 0);
  },
};
 
user.normal(); // usually undefined
user.arrow();  // Rajesh

Because the arrow function uses this from arrow() where this === user.


Most common interview questions

Q1: Why does this become undefined here?

const obj = {
  x: 1,
  getX() { return this.x; }
};
 
const get = obj.getX;
get();

Because you lost the call-site (obj.).

Fix:

const get = obj.getX.bind(obj);
get(); // 1

Q2: Does bind work on arrow functions?

No. Arrow functions ignore bind/call/apply for this.

Q3: What’s best practice in React?

  • Prefer arrow functions or bind in constructor (class components).
  • In function components, avoid relying on this.

Summary checklist

  • I can list the 4 binding rules.
  • I can explain why const fn = obj.method; fn() breaks.
  • I know arrow functions ignore bind/call/apply for this.

Summary

  • Normal function this depends on call-site.
  • call/apply/bind set this explicitly.
  • new creates a new this.
  • Arrow functions have lexical this.