[JavaScript] A Comprehensive Guide to call, apply, and bind Methods

Tech Some Notes
5 min readJan 7, 2024

--

Photo by Scott Webb on Unsplash

In the world of JavaScript, objects play an important role, and the keyowrd this is central to understanding the context in which a function is executed. In other words, this refers to the object that invokes the function.

However, value of this becomes relatively dynamic depending on the context it belongs to, making it sometimes tricky to determine the accurate value of this. Or, you just simply want to replace the value of this inside a function with whatever you want.

Therefore, we are going to explore the three methods: call, bind and apply, and how they offer precise control over the binding of this in JavaScript functions.

What are call, apply and bind?

As mentioned earlier, call, apply, and bind are three methods that help us to manipulate the value of this within a function. However, distinctions exist among them.

  1. call: This method serves the purpose of replacing the context of the invoking function. It immediately executes the function and returns the result.
  2. apply: This methis is very similar to the call function, differing only in the manner in which arguments are passed. We will see examples in the later paragraphs.
  3. bind: It is a function that creates another function with a pre-determined bound this value based on the provided input.

How to use the function: call()?

  • Here is the syntax of the call funtion:
function.call(thisArg, arg1, arg2, ...)
  • function: It is the function that needs to be invoked with a specific this object.
  • thisArg: It is the object given to replace the this keyword inside the function.
  • arg1, arg2, … : These are the original arguments for the function; their order is moved one index after in parallel. If no parameters are required in the target function, just do not pass them in.

How to use the function: apply()?

Here is the syntax of the apply funtion:

function.apply(thisArg, [args1, arg2, ...])
  • function: It is the function that needs to be invoked with a specific this object (similarly to the useage of the call function).
  • thisArg: It is the object given to replace the this keyword inside the function (similarly to the useage of the call function).
  • [arg1, arg2, ...]: Its parameters are passed into the target function in array form

How to use the function: bind()?

Here is the syntax of the bind funtion:

function.bind(thisArg, arg1, arg2, ...)
  • function : The target function won’t be invoked immediately; instead, a new function with a specific this keyword will be created.
  • thisArg: It is the object given to replace the this keyword inside the new function.
  • arg1, arg2, … : These are the original arguments for the function (similarly to the useage of the call function).

A classic example of missing this…

Let’s examine the example below featuring a class named Student. In this class, we require two parameters: firstName and lastName. Additionally, two functions are defined: firstGreet and a callback function named laterGreet.

If we create an instance, let’s say “lizzy,” and invoke both methods, what would happen? Does it get the correct this?

It turns out that the firstGreet function works as expected when invoked. It correctly identifies the firstName as "lizzy" and logs it properly. However, there's an issue with the laterGreet callback function.

Why is that? The problem arises because setTimeout is a callback function executed in the global context. As the result, the this keyword refers to the global object, which, in the browser environment, is typically the window object. The window object lacks the lastName "Kim," leading to the missing information in the callback function.

How to solve the problem?

1.Use bind() :

The first solution is to manually bind this in the callback function to the instance of Student. We can we can modify the code to bind the correct this value to the laterGreet function.

By doing this, we ensure that when the setTimeout callback is executed, it refers to the correct instance of the Student class.

// Rewrite the laterGreet method with bind method

laterGreet() {
setTimeout(function() {
console.log('(1 sec...) Hi!, I am ', this.lastName);
}.bind(this), 1000);
}

2. Arrow function:

The second solution is to use arrow functions to address the context issue within the setTimeout callback. Unlike regular functions, arrow functions don’t bind their own this value. Instead, they inherit the this value from the enclosing scope.

In the example, replacing the regular function inside setTimeout with an arrow function allows it to capture the this value from the surrounding laterGreet method. This ensures that the this context remains associated with the instance of the Student class.

// Rewrite the laterGreet method with an arrow function

laterGreet() {
setTimeout(() => {
console.log('(1 sec...) Hi!, I am ', this.lastName});
}, 1000);
}

3. Save this as a const

The third solution is saving the value of this in a constant variable (self, that, or any chosen name). By doing so, you can preserve the original this reference and use it within nested functions or callbacks.

// Rewrite the laterGreet method with self the constant

laterGreet() {
setTimeout(function() {
const self = this;
console.log('(1 sec...) Hi!, I am ', self.lastName);
}, 1000);
}

Conclusion

Understanding these methods — call, apply, and bind — offers an useful toolkit for developers who look for precise control over the value of this within funtions.

I hope the explanation above could benefit anyone who may find themselves confused by the keyword this . Understanding how this behaves in different contexts is important for navigating the language effectively, so as its solutions if you want to control the value of this .

Enjoy!

Reference

[How to Use the Call, Apply, and Bind Functions in JavaScript — with Code Examples]
https://www.freecodecamp.org/news/understand-call-apply-and-bind-in-javascript-with-examples/

--

--

Tech Some Notes
Tech Some Notes

Written by Tech Some Notes

I am TY Liang, a frontend software engineer from Taiwan with a diverse skill set in Next.js, React, TypeScript, UI/UX design, API integration, and so on.