
Understanding call, apply, and bind in JavaScript

JavaScript's this keyword often confuses front‑end developers, especially when working with functions. Understanding how to control the value of this will make your life as a front‑end developer much easier for you and your colleagues: it will allow you to write cleaner and more predictable code.
That's where call, apply, and bind come in. These methods provide us with powerful tools for setting the this context. In this article, I intend to explore what these methods are, how they differ, and when you should use each one. By the end, you'll hopefully have a decent grasp of how to leverage them effectively within your projects.
What Are call, apply, and bind?
At their core, call, apply, and bind are all methods available on every JavaScript function. They allow you to explicitly set the value of this when invoking a function, which gives us control over its execution context.
call
The call method invokes a function with a specified this value and arguments provided one by one. For example:
function greet(greeting, name) { console.log(`${greeting}, ${name}! My context is:`, this);}greet.call({ role: 'developer' }, 'Hello', 'Maddie');// Output: Hello, Maddie! My context is: { role: 'developer' }apply
The apply method is similar to call, but it expects arguments in the form of an array:
const numbers = [5, 10, 15];const max = Math.max.apply(null, numbers);console.log(max); // Output: 15bind
The bind method is a little different, it doesn't execute the function immediately. Instead, it returns a new function with the specified this value permanently bound to it:
const user = { name: 'Sophie' };function introduce() { console.log(`My name is ${this.name}`);}const boundIntroduce = introduce.bind(user);boundIntroduce(); // Output: My name is SophieAll three of these methods are particularly useful when you need to explicitly define the this context, such as borrowing methods from other objects, working with callbacks, or ensuring consistent context in asynchronous functions.
What is call in JavaScript?
The call method is a built‑in JavaScript function available on all functions. It allows us to invoke a function whilst explicitly specifying the value of this. This can be incredibly useful when borrowing methods from other objects or when you need granular control over a function's context.
Syntax of call
functionName.call(thisArg, arg1, arg2, ...);thisArg: The value you want to use as thethiscontext for the function.arg1, arg2, ...: Additional arguments passed to the function.
Using call to Borrow Methods
One of the most common use cases for call is borrowing methods from elsewhere in the codebase. For example, if you want to use an array method on a different type of object, you could use call to make it work:
const person = { firstName: 'John', lastName: 'Doe', fullName: function () { return `${this.firstName} ${this.lastName}`; },};const anotherPerson = { firstName: 'Jane', lastName: 'Smith' };// Borrowing fullName method for anotherPersonconsole.log(person.fullName.call(anotherPerson)); // Output: "Jane Smith"Passing Arguments with call
We can also pass arguments directly to the function that we're calling:
function greet(greeting, punctuation) { console.log(`${greeting}, ${this.name}${punctuation}`);}const user = { name: 'Ellie' };// Invoking greet with a custom `this` and argumentsgreet.call(user, 'Hello', '!'); // Output: "Hello, Ellie!"Key Considerations
- If
thisArgisnullorundefined, the defaultthiswill be the global object (windowin browsers,globalin Node.js). In strict mode,thiswill beundefined. - Unlike
apply, which we'll discuss in a minute,callrequires individual arguments to be passed, not an array.
What is apply in JavaScript?
The apply method is fairly similar to call in that it allows you to invoke a function whilst explicitly specifying the value of this. However, apply differs in how it handles additional arguments. Instead of passing them individually, apply expects an array‑like object as the second argument.
Syntax of apply
functionName.apply(thisArg, [arg1, arg2, ...]);thisArg: The value to use asthisinside the function.[arg1, arg2, ...]: An array or array‑like object containing arguments for the function.
Using apply to Borrow Methods
Just like with call, apply is useful for borrowing methods. The key difference is that apply simplifies scenarios where arguments are already in an array or array‑like object. For example:
const numbers = [5, 10, 15, 20];const maxNumber = Math.max.apply(null, numbers);console.log(maxNumber); // Output: 20In this example, apply makes it easy to pass the array of numbers to Math.max.
Example with apply
Here's another quick and practical example:
function introduce(greeting, punctuation) { console.log(`${greeting}, my name is ${this.name}${punctuation}`);}const person = { name: 'Ellie' };const args = ['Hello', '!'];introduce.apply(person, args); // Output: "Hello, my name is Ellie!"Key Considerations
- As with
call, ifthisArgisnullorundefined, the function will default to the global object (orundefinedin strict mode). - Use
applywhen arguments are already in an array or need to be dynamically constructed.
What is bind in JavaScript?
Compared to call and apply, the bind method is relatively unique. Instead of immediately invoking the function, bind returns a new function with this permanently set to the value we specify. This can be especially useful for creating function references with a fixed context.
Syntax of bind
const boundFunction = functionName.bind(thisArg, arg1, arg2, ...);thisArg: The value to use as this inside the new function.arg1, arg2, ...: Optional arguments that are pre‑set when the function is called.
Using bind for Function Context
Here's a quick example:
const user = { name: 'Maddie', greet: function () { console.log(`Hello, ${this.name}!`); },};const greetUser = user.greet.bind(user);// Even if `greetUser` is called in a different context, `this` is preservedgreetUser(); // Output: "Hello, Maddie!"Pre‑setting Arguments with bind
We using bind, it is also possible to pre‑set arguments, like this:
function multiply(a, b) { return a * b;}const double = multiply.bind(null, 2); // `a` is pre-set to 2console.log(double(5)); // Output: 10In this example, the bind method is used to create a new function, double, where the first argument of the multiply function (a) is permanently set to 2. When double is invoked with a single argument (5), it effectively calls multiply(2, 5) and returns the result, 10.
Here, we're demonstrating how bind can pre‑set certain arguments, making it a powerful tool for creating specialized versions of functions tailored to specific needs or contexts.
Key Considerations
bindis ideal for event handlers or callbacks where preservingthisis important.- The returned function from
bindcan still accept additional arguments beyond those pre‑set.
When to Use call, apply, and bind
Understanding when to use each method is key to leveraging their strengths effectively. Here's a breakdown of typical use cases for each:
call
Use call when you need to immediately invoke a function with a specific this context and explicitly list the arguments. It's great for scenarios where you know the arguments in advance, such as when borrowing methods or performing inline function invocations.
For example, borrowing a method from another object:
const person = { name: 'John',};function introduce(age) { console.log(`Hi, I'm ${this.name} and I'm ${age} years old.`);}introduce.call(person, 30);// Output: Hi, I'm John and I'm 30 years old.apply
Use apply when you need to immediately invoke a function, in much the same way as with call, but the arguments are already in an array or an array‑like structure. This is especially useful in scenarios where the arguments are dynamically generated or come from another function.
For example, finding the maximum value in an array:
const numbers = [5, 1, 7, 3];const maxNumber = Math.max.apply(null, numbers);console.log(maxNumber); // Output: 7bind
Use bind when you want to create a new function with a specific this context or pre‑set arguments, but delay its execution. It is perfect for event handlers, callbacks, or scenarios where you need to reuse the function in different contexts.
For example, customising a function for repeated use:
const printer = { prefix: 'Message:',};function printMessage(message) { console.log(`${this.prefix} ${message}`);}const boundPrinter = printMessage.bind(printer);boundPrinter('Hello, World!');// Output: Message: Hello, World!Wrapping up
The call, apply, and bind methods play crucial roles in JavaScript, offering developers powerful tools to control the this context within functions. Whether you're invoking a function immediately with dynamic arguments, working with arrays of arguments, or creating reusable functions with pre‑set contexts, these methods ensure flexibility and clarity within your code.
Key Takeaways
call: Invokes a function immediately, with arguments provided individually.apply: Similar tocall, but expects arguments as an array, making it particularly useful for scenarios like using theMathmethods.bind: Creates a new function with a permanently boundthisvalue, useful for event handlers and partial application.- These methods are essential for managing this dynamically and writing more maintainable code.
- Understanding when and where to use each method is a key skill for any JavaScript developer.
In JavaScript, the ability to control the this context dynamically is invaluable, and call, apply, and bind provide the flexibility to do so effectively. With these tools in your arsenal, you'll be better equipped to handle complex coding challenges and write more adaptable, efficient code.
Related Articles

Appending and Prepending Items to an Array. 
Exploring the call() Method in JavaScript. Exploring the
call()Method in JavaScript
Understanding prototype.apply() in JavaScript. Understanding
prototype.apply()in JavaScript
Harnessing the Power of Prototype.bind(). Harnessing the Power of
Prototype.bind()
Trigonometric Functions in CSS. Trigonometric Functions in CSS

Controlling Element Transparency with CSS opacity. Controlling Element Transparency with CSS
opacity
Spread Syntax in JavaScript (...). Spread Syntax in JavaScript (
...)
Dynamically Create a Script Element with JavaScript. Dynamically Create a Script Element with JavaScript

React Portals Explained. React Portals Explained

Promise.all() vs. Promise.race() in JavaScript. Promise.all()vs.Promise.race()in JavaScript
Using Vue's Teleport for Modals and Portals. Using Vue's Teleport for Modals and Portals

How to Use and Clear the CSS float Property. How to Use and Clear the CSS
floatProperty