Tips on this, call, apply, and bind
Table of Contents
Introduction
When we’re working with JavaScript, call
, apply
, and bind
are methods used to control how a function is executed and what context it runs in. By context, I mean its this
value, which refers to the object that is currently executing the function. Using these methods, you can specify which object should be treated as this
inside the function, allowing for greater flexibility and control in your code. Practically speaking, this is important because it means we use them to manipulate the execution context of a function, outside of it’s original object.
Practical example
"use strict";
// Define a character object with a method to describe an attack
;
// Another character object
;
// Using call to invoke the attack method with a different context
anotherCharacter, "staff", 15;
// Output: Luna the Mage attacks with a staff causing 15 damage!
// Using apply to invoke the attack method with a different context and an array of arguments
anotherCharacter,;
// Output: Luna the Mage attacks with a magic spell causing 20 damage!
// Using bind to create a new function with a preset context
;
10; // Later we can specify the damage
// Output: Luna the Mage attacks with a wand causing 10 damage!
// Bind can also preset the context without presetting arguments
;
25;
// Output: Ted the Warrior attacks with a sword causing 25 damage!
// Using call, apply, and bind together in a practical scenario
// Define a function that logs an action with multiple steps
// Using bind to set context and partial arguments
;
// Using call to invoke the partially bound function with additional arguments
character, "swing sword", "deflect";
// Using apply to invoke the partially bound function with additional arguments as an array
character,;
// Output (for both call and apply):
// Ted the Warrior starts with block with shield, then swing sword, and finally deflect.
Above, we have a character
object with a method attack
that logs an attack message.
Another object, anotherCharacter
, represents a different character. Using call
, we make anotherCharacter
use the attack
method: character.attack.call(anotherCharacter, "staff", 15)
. The apply
method does the same but takes arguments as an array: character.attack.apply(anotherCharacter, ["magic spell", 20])
.
The bind
method creates a new function with a preset context, allowing anotherCharacter
to attack later: const lunaAttack = character.attack.bind(anotherCharacter, "wand")
.
We then use call
and apply
with bind
to perform complex actions: thorinPerformAction.call(character, "swing sword", "deflect")
and thorinPerformAction.apply(character, ["swing sword", "deflect"])
.
Why is this significant?
Because we can instantiate dynamic context. We also have flexibility in function arguments. call
allows us to pass arguments individually, we get fine-tuned control over the function execution. With apply
, we can accept arguments in an array format. With this, we can “borrow methods”. This is important because it means we can use a method from one object on another, which helps us avoid redundancy but allows us to reuse code. We’re also able to use the partial function application of it because bind
creates a new function that has optional preset arguments.
Until the, have a great day!