this, call, apply, and bind in JavaScript
πΉ 1. Understanding thisβ
thisrefers to the execution context (who is calling the function).- Its value depends on how a function is called, not where itβs defined.
1.1 this in Global Scopeβ
console.log(this);
// In browser β Window object
// In Node.js β {}
1.2 this in Normal Functionβ
function showThis() {
console.log(this);
}
showThis();
// In strict mode β undefined
// Non-strict β Window (browser)
1.3 this in Object Methodβ
const obj = {
name: "Shyam",
greet: function() {
console.log(this.name);
}
};
obj.greet(); // "Shyam"
π this refers to the object (obj).
1.4 this in Arrow Functionβ
const obj = {
name: "Shyam",
greet: () => {
console.log(this.name);
}
};
obj.greet(); // undefined (Arrow doesnβt bind its own `this`)
π Arrow functions capture this from their lexical scope (where they are defined).
1.5 this Inside a Function in Objectβ
const obj = {
name: "Shyam",
nested: {
show: function () {
console.log(this.name);
}
}
};
obj.nested.show(); // undefined (because `this` refers to `nested`, not `obj`)
1.6 this in Constructor Functions / Classesβ
function Person(name) {
this.name = name;
}
const p1 = new Person("Shyam");
console.log(p1.name); // "Shyam"
π In constructor, this points to the new object created.
1.7 Event Handlersβ
document.querySelector("button").addEventListener("click", function () {
console.log(this); // button element
});
document.querySelector("button").addEventListener("click", () => {
console.log(this); // lexical `this` (likely Window)
});
πΉ 2. call, apply, and bindβ
These methods manually control the value of this.
2.1 call()β
- Calls a function with a given
thisand arguments passed individually.
function greet(greeting, punctuation) {
console.log(`${greeting}, ${this.name}${punctuation}`);
}
const user = { name: "Shyam" };
greet.call(user, "Hello", "!"); // Hello, Shyam!
2.2 apply()β
- Similar to
call(), but arguments are passed as an array.
greet.apply(user, ["Hi", "!!!"]); // Hi, Shyam!!!
2.3 bind()β
- Returns a new function with
thispermanently bound. - Doesnβt call immediately.
const boundGreet = greet.bind(user, "Hey");
boundGreet("?"); // Hey, Shyam?
π You can pass variables later to the bound function.
πΉ 3. Core Differencesβ
| Feature | call | apply | bind |
|---|---|---|---|
| Execution | Calls function instantly | Calls function instantly | Returns new function (delayed) |
| Arguments | Passed individually | Passed as array | Passed partially (later possible) |
| Use Case | Direct function invoke | When args are already in array | Event handlers, callbacks |
πΉ 4. Real-World Examplesβ
Example 1: Borrowing Methodsβ
const person1 = { name: "Alice" };
const person2 = { name: "Bob" };
function sayHello() {
console.log(`Hello, ${this.name}`);
}
sayHello.call(person1); // Hello, Alice
sayHello.call(person2); // Hello, Bob
Example 2: Math with applyβ
const numbers = [5, 2, 9, 1];
console.log(Math.max.apply(null, numbers)); // 9
Example 3: bind for Event Handlersβ
class Button {
constructor(label) {
this.label = label;
}
click() {
console.log(`${this.label} clicked`);
}
}
const b = new Button("Save");
document.querySelector("button")
.addEventListener("click", b.click.bind(b));
Example 4: Partial Application with bindβ
function multiply(a, b) {
return a * b;
}
const double = multiply.bind(null, 2);
console.log(double(5)); // 10
πΉ 5. Why Do They Exist in JS?β
- To control context (
this) explicitly. - To borrow functions between objects.
- To implement function currying / partial application.
- To handle callbacks where
thisis lost (e.g., event listeners, setTimeout).
πΉ 6. Interview Questions (Basic β Advanced)β
πΉ Basicsβ
- What is
thisin JavaScript? How does it differ in arrow vs normal functions? - Difference between
call,apply, andbind. - What is the default value of
thisin strict mode vs non-strict mode?
πΉ Intermediateβ
- Can you use
bindto implement partial functions? Example? - Why do we need
bindin event handlers in React/JS? - What happens if you use
newwith a function thatβs bound withbind? - How does
thisbehave inside asetTimeout?
πΉ Advanced / Trickyβ
-
Why canβt arrow functions be used as constructors with
new? -
Can you re-bind a function multiple times? What will happen?
const f = greet.bind(user1).bind(user2);
f(); // Who will it bind to? -
How would you polyfill
call,apply, andbind? -
How does
thisbehave in nested objects? Example:const obj = {
a: 10,
inner: {
a: 20,
show: function () {
console.log(this.a);
}
}
};
obj.inner.show(); // ?
β
This is enough to handle 90% of interview questions around this, call, apply, and bind.