call()
call() lets you run a function immediately with a specific this value.
function greet() {
return `Hello, ${this.name}`;
}
const user = {
name: "Alice",
};
console.log(greet.call(user)); // Hello, AliceThe important part:
greet.call(user)This calls greet and sets this to user for that call.
Basic Syntax
functionName.call(thisValue, arg1, arg2, arg3);The first argument is the value of this.
The remaining arguments are passed into the function normally.
call() Runs Immediately
Unlike bind(), call() does not return a new function for later.
It runs the function now.
function sayName() {
console.log(this.name);
}
const user = {
name: "Alice",
};
sayName.call(user); // AliceThe function runs immediately.
call() With Arguments
function introduce(role, city) {
return `${this.name} is a ${role} from ${city}`;
}
const user = {
name: "Alice",
};
const message = introduce.call(user, "developer", "Delhi");
console.log(message); // Alice is a developer from DelhiHere:
thisisuserroleis"developer"cityis"Delhi"
Arguments after the first one are passed one by one.
Borrowing Methods
call() can let one object use a method from another object.
const user = {
name: "Alice",
describe() {
return `User: ${this.name}`;
},
};
const admin = {
name: "Ava",
};
console.log(user.describe.call(admin)); // User: AvaThe method belongs to user, but for this call, this is admin.
This is called method borrowing.
Reusing Generic Functions
Instead of putting the same method on many objects, you can write one function and call it with different objects.
function describeUser() {
return `${this.name} has role ${this.role}`;
}
const alice = {
name: "Alice",
role: "admin",
};
const bob = {
name: "Bob",
role: "editor",
};
console.log(describeUser.call(alice)); // Alice has role admin
console.log(describeUser.call(bob)); // Bob has role editorThe same function works with different contexts.
call() Does Not Permanently Bind
call() only affects one function call.
function sayName() {
console.log(this.name);
}
const alice = { name: "Alice" };
const ava = { name: "Ava" };
sayName.call(alice); // Alice
sayName.call(ava); // AvaEach call can use a different this.
If you need a reusable function with fixed this, use bind().
call() vs Direct Method Call
These can produce the same result:
const user = {
name: "Alice",
greet() {
return `Hello, ${this.name}`;
},
};
console.log(user.greet()); // Hello, Alice
console.log(user.greet.call(user)); // Hello, AliceThe direct method call is simpler.
Use call() when you need to choose or change the context explicitly.
call() With null or undefined
If a function does not use this, you may see null as the first argument.
function add(a, b) {
return a + b;
}
console.log(add.call(null, 2, 3)); // 5Here this does not matter.
The main reason to use call() here would be consistency or metaprogramming, not normal beginner code.
call() and Arrow Functions
call() cannot change an arrow function's this.
const user = {
name: "Alice",
};
const greet = () => {
console.log(this.name);
};
greet.call(user); // not AliceArrow functions use lexical this.
Use a regular function when you need call().
call() vs bind()
| Method | Calls immediately? | Returns new function? |
|---|---|---|
call() |
Yes | No |
bind() |
No | Yes |
Example:
greet.call(user); // runs nowconst boundGreet = greet.bind(user); // creates function
boundGreet(); // runs laterBest Practices
Use call() when you want to run a function now with a chosen this.
fn.call(context, arg1, arg2);Use bind() when you need to save the function for later.
Do not use call() when a normal method call is clearer.
Use regular functions when you need call() to control this.
Remember that call() only affects one invocation.
Common Mistakes
Mistake 1: Thinking call() Returns a Bound Function
const result = greet.call(user);This stores the return value of greet, not a bound function.
If you need a bound function:
const bound = greet.bind(user);Mistake 2: Passing Arguments as an Array
introduce.call(user, ["developer", "Delhi"]);This passes one array argument.
With call, pass arguments one by one:
introduce.call(user, "developer", "Delhi");Use apply() if your arguments are already in an array.
Mistake 3: Using call() on an Arrow Function to Change this
arrowFn.call(user);This does not change the arrow function's lexical this.
Quick Check
What does this log?
function sayRole() {
console.log(this.role);
}
const user = {
role: "admin",
};
sayRole.call(user);It logs:
adminDoes call() run the function immediately?
Yes.
Summary
call() runs a function immediately with a chosen this.
- The first argument to
call()becomesthis. - Remaining arguments are passed one by one.
call()is useful for method borrowing and explicit context.call()does not permanently bind a function.- Use
bind()when you need a function for later. - Use
apply()when arguments are already in an array. call()cannot change arrow functionthis.