Skip to main content

Command Palette

Search for a command to run...

JavaScript Power Trio: Mastering Call, Apply, and Bind

Updated
3 min read

If you have been working with JavaScript for a while, you’ve likely bumped into the this keyword. It’s powerful, but it can be slippery. Sometimes this doesn’t refer to what you think it does.

This is where Call, Apply, and Bind come to the rescue. These three methods allow you to explicitly determine what this refers to, giving you full control over the execution context of your functions.

Let's break them down.

The Setup: A Real-World Example

Imagine we have a person object with a first and last name. We also have a standalone function greet that is not attached to the object but uses this to access data.

JavaScript

const person1 = {
  firstName: "John",
  lastName: "Doe"
};

const person2 = {
  firstName: "Sarah",
  lastName: "Smith"
};

function greet(greeting, punctuation) {
  console.log(`${greeting}, ${this.firstName} ${this.lastName}${punctuation}`);
}

If you try to run greet("Hello", "!") on its own, it will fail (or print undefined) because this doesn't point to person1 or person2. It points to the global window object.

We need a way to tell the function: "Hey, run this code, but pretend this is person1."

1. Call: The Direct Dial

The call() method invokes a function immediately and allows you to pass in arguments one by one.

Syntax: function.call(thisArg, arg1, arg2, ...)

Let's use it to make our greet function work with person1:

JavaScript

// The first argument is the object we want 'this' to refer to.
// The subsequent arguments are the parameters for the function.
greet.call(person1, "Hello", "!"); 

// Output: Hello, John Doe!

We can easily switch the context to person2 just by changing the first argument:

JavaScript

greet.call(person2, "Hi", "."); 

// Output: Hi, Sarah Smith.

Key Takeaway: Use call when you want to invoke a function immediately and pass arguments individually.

2. Apply: The Array Approach

The apply() method is almost identical to call(). The only difference is how it handles function arguments. Instead of passing arguments one by one, you pass them as a single array.

Syntax: function.apply(thisArg, [argsArray])

JavaScript

const args = ["Good morning", "!!!"];

// We pass the arguments as an array
greet.apply(person1, args); 

// Output: Good morning, John Doe!!!

Key Takeaway: Use apply when your arguments are already in an array or list format. A handy mnemonic: Apply takes an Array.

3. Bind: The Permanent Connection

Both call and apply execute the function immediately. But what if you don't want to run the function right now? What if you want to create a version of the function that you can use later, but with this permanently set to a specific object?

That is what bind() does. It returns a new function instance.

Syntax: const newFunc = function.bind(thisArg, arg1, arg2, ...)

JavaScript

// Create a new function where 'this' is permanently bound to person2
const greetSarah = greet.bind(person2);

// We can run this new function whenever we want
greetSarah("Greetings", "."); 
// Output: Greetings, Sarah Smith.

// Even if we try to override it, 'this' stays bound to person2
greetSarah.call(person1, "Yo", "!"); 
// Output: Yo, Sarah Smith! (Still Sarah!)

Key Takeaway: Use bind when you want to set the this value now but execute the function later (commonly used in event listeners and React components).

Summary

MethodExecutionArgumentsUsage
CallImmediateComma separated (arg1, arg2)When you have individual arguments.
ApplyImmediateArray ([arg1, arg2])When arguments are in a list/array.
BindLater (Returns a function)Comma separatedWhen you need a function to be called later with a specific context.

Mastering these three methods gives you the ability to borrow methods from other objects and write cleaner, more reusable JavaScript code. Happy coding!