JavaScript Runtime

call() vs apply() vs bind()

Learn how to explicitly set this, reuse functions, preserve method context, and create reusable callbacks.

Compare immediate execution, array arguments, deferred execution, method borrowing, event handlers, React class patterns, and partial application.

Why these methods exist

A function can be reused with different objects instead of copied into every object. call(), apply(), and bind() all explicitly set this, but they differ in when they execute and how they receive arguments.

one function → different this values → reusable behavior

Think of one ID-card scanner serving many employees: the scanner is shared, but the employee context changes.

call(): individual arguments
function greet(city) {
  return `Hi, I'm ${this.name} from ${city}`;
}

const user = { name: "Zubair" };
greet.call(user, "Lahore");

call sets this and executes immediately. Arguments are supplied one by one.

apply(): array arguments
function greet(city, country) {
  return `${this.name}, ${city}, ${country}`;
}

greet.apply(user, ["Lahore", "Pakistan"]);

apply is like call, but receives arguments as an array or array-like value.

bind(): execute later
function greet() {
  console.log(this.name);
}

const sayHello = greet.bind(user);
sayHello();

bind does not execute now. It returns a new function with this fixed for later.

bind(): partial application
function multiply(a, b) {
  return a * b;
}

const double = multiply.bind(null, 2);
double(5); // 10

bind can pre-fill arguments as well as binding this.

Compare the methods

Choose a method to see its execution behavior and argument style.

greet.call(user, "Lahore")executes now
call vs apply vs bind
Featurecall()apply()bind()
Sets thisYesYesYes
Executes immediatelyYesYesNo
Returns a new functionNoNoYes
ArgumentsSeparate valuesArraySeparate / stored
Common useImmediate borrowingArray-based invocationCallbacks and partial application
Borrow a method with call
const person = {
  firstName: "John",
  fullName() { return this.firstName; }
};

const employee = { firstName: "David" };
person.fullName.call(employee); // David

The same fullName function runs with employee as this; no method duplication is needed.

Fix a callback context
const user = {
  name: "John",
  greet() { console.log(this.name); }
};

setTimeout(user.greet.bind(user), 1000);
// John

bind returns a callback whose this remains user when the timer invokes it later.

React class binding
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.increment = this.increment.bind(this);
  }
}

Older React class components commonly bound event handlers so methods retained the component instance.

Partial application
function calculateTax(rate, amount) {
  return amount * rate;
}

const taxAtTenPercent =
  calculateTax.bind(null, 0.1);

taxAtTenPercent(100); // 10

bind can pre-fill arguments, creating a specialized reusable function.

Best Practices and Interview Answer

Use call() when arguments are separate values and execution should happen now.
Use apply() when arguments are already in an array or array-like value.
Use bind() for callbacks or reusable functions with fixed this.
Remember that bind() returns a function; it does not execute immediately.
call() and apply() cannot change the lexical this of an arrow function.
Avoid creating unnecessary bound functions inside frequently executed code.
Prefer arrow callbacks when they should inherit surrounding this.
Use a wrapper arrow or bind() when passing object methods to event handlers.

30-second answer: call(), apply(), and bind() explicitly set this. call() and apply() execute immediately; call() receives separate arguments while apply() receives an array. bind() returns a new function for later execution and can also pre-fill arguments.

Hands-on Exercises
Rewrite call with apply
greet.call(user, "Lahore", "Pakistan");
// Rewrite using apply()

Pass the same values in an array to apply().

Fix the timer
setTimeout(user.greet, 1000);
// Fix the lost this context

Create a bound callback with user.greet.bind(user).

Create a tax helper
function calculateTax(rate, amount) {}
// Create a reusable 10% function

Use bind(null, 0.1) to pre-fill rate.

Borrow displayInfo
const customer1 = { name: "John" };
const customer2 = { name: "Ali" };
function displayInfo() {}
// Call it for both objects

Use displayInfo.call(customer1) and displayInfo.call(customer2).

Practice quiz

call vs apply vs bind Quiz

Select an answer to see the explanation.

1. Which method executes a function immediately with individual arguments?

2. What is the main argument difference between call() and apply()?

3. What does bind() return?

4. Which method is most useful for setTimeout(user.greet, 1000)?

5. What is method borrowing?

6. Can call() change the this value of an arrow function?

7. What does multiply.bind(null, 2) demonstrate?

8. Which best practice is correct?

Score: 0 / 8