[JavaScript] A Comprehensive Guide to call, apply, and bind Methods
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.
- call: This method serves the purpose of replacing the context of the invoking function. It immediately executes the function and returns the result.
- 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.
- 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/