Understanding Call, Bind, and Apply in JavaScript: Manipulating Function Execution Context

Rahul Bharati
5 min readMar 12, 2023

JavaScript is a powerful programming language that can be used for a wide range of tasks, including web development, desktop applications, and mobile apps. Its support for functions, which are blocks of code that can be called and executed at any point in a program, is one of the features that makes it so versatile. In this article, we will look at three related methods for manipulating the execution context of JavaScript functions: call, bind, and apply.

Before we get into the specifics of these methods, let’s define the term “execution context.” When you call a function in JavaScript, a new execution context is created. This context contains information such as the this keyword’s value, the arguments passed to the function, and the scope chain. Understanding how to manipulate the execution context is essential for writing reusable code.

Call

The call method is a function method that can be used to invoke a function with a specified this value and arguments. The syntax for call is as follows:

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

The first argument to call is the thisArg, which is the value of the this keyword inside the function when it is called. If the function is a method of an object, thisArg should be set to that object. If the function is not a method of an object, thisArg can be set to null or undefined.

The remaining arguments to call are the arguments that will be passed to the function when it is called. For example, consider the following function:

function sayHello(name) {
console.log(`Hello, ${name}! My name is ${this.name}.`);
}

We can use the call method to invoke this function with a specific this value and argument:

const person = { name: 'Alice' };
sayHello.call(person, 'Bob');
// Output: Hello, Bob! My name is Alice.j

In this example, we have set the thisArg to the person object, so inside the function, the value of this is equal to person. We have also passed the argument ‘Bob’, which is used in the console.log statement.

Call can be useful in situations where you want to reuse a function with a different this value than it was originally defined with. For example, you may have a function that operates on an array, but you want to use it with a specific array that is not the global array. You can use call to achieve this:

const myArray = [1, 2, 3, 4, 5];

function sum() {
let total = 0;
for (let i = 0; i < this.length; i++) {
total += this[i];
}
return total;
}

const result = sum.call(myArray);
console.log(result); // Output: 15

In this example, we have defined a function sum that sums the values of an array. We have then used call to invoke this function with the thisArg set to myArray. This allows us to use the sum function on a specific array rather than the global array.

Bind

Another function method that can be used to set the value of this for a function is the bind method, which, unlike call, does not immediately invoke the function. Instead, it returns a new function with the same this value as the original function when called. The syntax for bind is as follows:

function.bind(thisArg, arg1, arg2, ...)

The first argument to bind is the thisArg, which is the value of the this keyword inside the returned function. The remaining arguments are the arguments that will be passed to the returned function when it is called.

For example, consider the following function:

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

We can use bind to create a new function that has the same behavior as greet, but with a specific this value and default arguments:

const person = { name: 'Alice' };
const greetAlice = greet.bind(person, 'Hi');
greetAlice('!'); // Output: Hi, Alice!

In this example, we have used bind to create a new function greetAlice that has the thisArg set to the person object, and the first argument set to ‘Hi’. When we call greetAlice with the argument ‘!’, it logs the message ‘Hi, Alice!’ to the console.

Bind can be useful in situations where you want to create a new function with a specific this value that can be called later. For example, you may have an event handler that needs to be bound to a specific object:

const button = document.querySelector('button');

const obj = {
count: 0,
handleClick: function() {
this.count++;
console.log(`Button clicked ${this.count} times`);
}
};

button.addEventListener('click', obj.handleClick.bind(obj));

In this example, we have defined an object obj with a count property and a handleClick method that logs a message to the console when called. We have then used bind to create a new function that has the thisArg set to obj, and passed this function as the event handler for a button click event. When the button is clicked, the handleClick method is called with the this value set to obj, allowing us to update the count property.

Apply

The apply method, like the call method, can be used to call a function with a specific this value and arguments. Instead of passing arguments individually as with call, apply takes as its second argument an array-like object containing the arguments to be passed to the function. The syntax for apply is as follows:

function.apply(thisArg, [arg1, arg2, ...])

The first argument to apply is the thisArg, which is the value of the this keyword inside the function when it is called. The second argument is an array-like object that contains the arguments to be passed to the function.

For example, consider the following function:

function sum(a, b, c) {
return a + b + c;
}

We can use apply to invoke this function with a specific this value and arguments:

const numbers = [1, 2, 3];

const result = sum.apply(null, numbers);
console.log(result); // Output: 6

In this example, we have set the thisArg to null since the sum function does not rely on the this keyword. We have also passed an array-like object numbers that contains the arguments to be passed to the function.

Apply can be useful in situations where you want to pass an array of arguments to a function, or when you want to dynamically generate arguments to be passed to a function.

Finally, call, bind, and apply are powerful JavaScript methods that allow you to manipulate the execution context of functions. Both call and apply allow you to invoke a function with a specific this value and arguments, but apply takes an array-like object as its second argument rather than individual arguments. Bind is distinct in that it returns a new function with a specific this value rather than invoking the original function immediately. Understanding how to use these methods effectively can help you write more flexible and reusable JavaScript code in your applications.

--

--

I’m a full-stack developer (MERN). I also like to read books, play guitar, and sketch.