If you've ever felt confused about how the this keyword works in JavaScript functions, or why you sometimes lose the intended context when passing functions around, you're not alone. JavaScript provides three powerful methods—call(), apply(), and bind()—that help control the value of this when invoking functions.
Whether you want to call a function immediately with a specific context, pass arguments flexibly, or create a new function with a fixed this for later use, these methods are your go-to tools.
In this post, we'll break down how each works, show you simple code examples, explain when to use them, and reveal some common mistakes to watch out for.
What are call, apply, and bind?
All three methods are found in JavaScript functions. They let you control what this means inside a function, and how arguments are passed. Here's what sets each apart:
1. How call() Works
Purpose: Instantly calls a function, setting its this and passing arguments one by one.
Signature: func.call(thisArg, arg1, arg2, ...)
Example:
Here, this inside sayHello is set to the user.
2. How apply() Works
Purpose: Nearly identical to call, but passes arguments as an array.
Signature: func.apply(thisArg, [arg1, arg2, ...])
Example:
When you want to spread an array of arguments, apply is your friend.
3. How bind() Works
Purpose: Doesn't immediately call the function—returns a new version with this bound (and can preset arguments).
Signature: let boundFunc = func.bind(thisArg, arg1, arg2, ...)
Example:
Use bind whenever you want to defer a function call but ensure it will use the right this.
Differences: Call vs Apply vs Bind
How Do They Work Under the Hood? Or Polyfills Implementation
Real-World Scenario: A Login Greeting System
- The call() method lets you invoke a function immediately and set the value of this manually. You also pass arguments one by one.
- When to use call(): When you already know the arguments and want to call the function instantly.
- The apply() method works just like call(), but it takes arguments as an array instead of listing them separately.
- When to use apply(): When your arguments are already in an array — for example, data coming from an API.
- Bonus example for apply():
- Unlike call() and apply(), the bind() method does not call the function immediately. Instead, it returns a new function that remembers the given this value and arguments.
- When to use bind(): When you want to store the function and use it later, for example, in event handlers or timers.
Arrow Functions vs bind(): Which is Better?
- You can bind the function inside the constructor as below.
- Efficient when bound once in the constructor
- Explicitly shows where context is fixed
- More code to write
- Easy to forget .bind(this)
- Looks a bit old-fashioned in modern React
Arrow Function vs bind()
Modern Alternatives
Common Mistakes & Gotchas
- Forgetting to call bind:
- Using bind/apply with arrow functions:
- Arrow functions ignore this from bind/call/apply!
- Overusing bind inside render—React:
- Don’t call .bind inside a render/loop; it creates new functions on every render and slows down your app.
