The Magic of this, call(), apply(), and bind()
Source: Dev.to
Hello readers 👋 – Welcome back to the 10th post in this JavaScript series
Imagine you’re at a party and someone shouts, “Hey, come here!” Who will respond? It depends on who is calling and who they’re looking at.
In JavaScript the this keyword works exactly like that. It’s a special identifier that refers to the context – the object that is currently calling the function.
Sometimes you want to control what this refers to. That’s where the magical trio call(), apply(), and bind() come into play.
this in JavaScript – The Simple Explanation
thisis a keyword that refers to the object that is executing the current function.- Think of it as a secret note that tells the function, “Hey, you’re working for this object right now.”
Simple rule: this refers to who is calling the function.
this Inside Normal Functions
function showThis() {
console.log(this);
}
showThis(); // In a browser: logs the window objectWhen the function is called from the global context, this points to window.
"use strict";
function showThis() {
console.log(this);
}
showThis(); // undefinedIn strict mode JavaScript does not default to the global object – this is undefined.
Remember: In regular functions,
thisdepends on how the function is called, not where it’s defined.
this Inside Objects (Methods)
const person = {
name: "Satya",
greet() {
console.log(`Hello, I’m ${this.name}`);
}
};
person.greet(); // Hello, I’m SatyaWhen a function is a property of an object (a method), this refers to that object.
What happens when you detach the method?
const greetFn = person.greet;
greetFn(); // Hello, I’m undefined (or window.name in non‑strict mode)greetFn is now a plain function, so this is no longer person.
This is where call, apply, and bind become useful – they let us explicitly set the value of this.
call(), apply(), and bind() – Controlling this
call()
- What it does: Calls a function with a specified
thisvalue and individual arguments. - Syntax:
functionName.call(thisArg, arg1, arg2, …)
const person1 = { name: "Raj" };
const person2 = { name: "Priya" };
function introduce(city, country) {
console.log(`${this.name} from ${city}, ${country}`);
}
introduce.call(person1, "Delhi", "India"); // Raj from Delhi, India
introduce.call(person2, "Mumbai", "India"); // Priya from Mumbai, IndiaReal‑life example
const car = {
brand: "Toyota",
getDetails(model) {
console.log(`${this.brand} ${model}`);
}
};
const anotherCar = { brand: "Honda" };
car.getDetails.call(anotherCar, "Civic"); // Honda CivicWe borrowed car.getDetails and invoked it with anotherCar as this.
apply()
- What it does: Same as
call(), but arguments are supplied as an array (or array‑like object). - Syntax:
functionName.apply(thisArg, [argsArray])
introduce.apply(person1, ["Delhi", "India"]); // Raj from Delhi, India
introduce.apply(person2, ["Mumbai", "India"]); // Priya from Mumbai, IndiaWhen to use apply
- Your arguments are already in an array.
- You need to pass a variable number of arguments.
const numbers = [10, 20, 30, 40];
console.log(Math.max.apply(null, numbers)); // 40(Here this doesn’t matter, so we pass null.)
bind()
- What it does: Does not call the function immediately. It returns a new function with
thispermanently set to the provided value (and optionally pre‑filled arguments). - Syntax:
const boundFn = functionName.bind(thisArg, arg1, arg2, …)
const person = { name: "Satya" };
function greet(greeting) {
console.log(`${greeting}, I’m ${this.name}`);
}
const boundGreet = greet.bind(person, "Hello");
boundGreet(); // Hello, I’m SatyaReal‑life example
const user = {
name: "Amit",
sayHi() {
console.log(`Hi, ${this.name}`);
}
};
// Pass the method to a button click handler
const sayHiFn = user.sayHi.bind(user);
// Later, when sayHiFn is called, it still uses `user` as `this`
sayHiFn(); // Hi, AmitWithout bind, passing user.sayHi directly would cause this to become the button element (or the global object).
Quick Comparison Table
| Method | When is the function called? | How are arguments passed? | Typical use case |
|---|---|---|---|
call() | Immediately | Individually, separated by commas | You know the arguments and want to invoke right away |
apply() | Immediately | As an array (or array‑like) | Arguments already in an array, or you have a variable number of them |
bind() | Later (returns a new function) | Individually (can pre‑fill) | Need a function with a fixed this for callbacks, event handlers, etc. |
Simple Mnemonics
- Call – Comma‑separated arguments.
- Apply – Array of arguments.
- Bind – Borrow & Bind for later use.
Key Takeaways
thisalways points to who is calling the function.- In regular functions (non‑methods)
thisis the global object (orundefinedin strict mode). - In methods,
thisis the object the method is called on. call()andapply()immediately invoke the function with a specifiedthis.bind()returns a new function withthispermanently set, ready to be called later.- Use
callfor comma‑separated arguments,applyfor array arguments, andbindwhen you need a reusable function with a fixed context.
Understanding this and these three methods will save you from many bugs and give you super‑powers in controlling function execution.
Practice the examples above, experiment with your own code, and watch your confidence with JavaScript’s context grow! 🚀
Soon it’ll become second nature.
Hope you liked this blog. If there’s any mistake or something I can improve, do tell me.
You can find me on LinkedIn and X – I post more stuff there.