Like applying cold water to a burned area in the real world, we can also apply
additional information to our function calls in the digital world.
Recently, I tried to clear the confusion around JavaScript’s this keyword and I briefly touched on bind
and call
. But this time, I would like to give a more in-depth look on them with some addition about apply
.
Let’s go in order, according to the title, and start with bind. But first, we need some code to demonstrate all three of them, so take a look at the following:
const currentYear = new Date().getFullYear();
const spongebob = {
name: 'Spongebob Squarepants',
dob: 1986,
species: 'sea sponge',
greet(qoute) {
console.log(`Hey, it's me, ${this.name} and I'm ${currentYear - this.dob} years old`);
qoute && console.log(qoute); // If we have a quote, log it out
}
};
const patrick = {
name: 'Patrick Star',
dob: 1978,
species: 'starfish',
greet(qoute) {
console.log(`Hey, it's me, ${this.name} and I'm ${currentYear - this.dob} years old`);
qoute && console.log(qoute);
}
};
Bind
bind
is used in JavaScript to bind certain context to a function. When you have a function called funky
and you call it like this: funky.bind(soul)
, you are actually creating a new function where the context of this
is set to the value of soul. Keep in mind that this does not modify the original function nor will it call.
// Since bind doesn't modify the original function, this.name will still be "Spongebob".
spongebob.greet.bind(patrick);
spongebob.greet(); // Hey, it's me, Spongebob...
// Assigning the bound greet to a variable and calling that will give back Patrick's details.
const greetPatrick = spongebob.greet.bind(patrick);
greetPatrick(); // Hey, it's me, Patrick...
The above code example demonstrates that bind
does not change the actual function but creates a brand new one. When we greetPatrick()
the second time, we get back Patrick’s details because of the bound context, even though we are calling spongbob.greet
.
Call
Unlike bind
, call
will actually call the function immediately with the specified context. Let’s take a look at the following:
// This will immediately calls greet with the context of patrick.
spongebob.greet.call(patrick);
// Since we call the function right away, the value of greetPatrick will be the return value
// When we don't have an explicit return statement eg.: 'return true;', "undefined" is returned implicitly
const greetPatrick = spongebob.greet.call(patrick);
console.log(greetPatrick); // undefined
spongebob.greet.call(spongebob, 'I\'m a good noodle!');
On line:9, we call Spongebob with the spongebob
context and for the argument, we are passing in a string. This line is essentially equivalent to the following:
spongebob.greet('I\'m a good noodle!');
Apply
Apply
functions as call
. The only difference between the two is that while call
accepts a list of arguments, apply
accepts an array of arguments.
patrick.greet.apply(patrick, ['Is mayonnaise an instrument?']);
Note the difference between call
and apply
. One is called with an array while the other is not. If we were to have multiple arguments they would look the following:
// Accepts list of arguments
spongebob.greet.call(spongebob, 'Believe it or not', 'I\'m a good noodle!');
// Accepts array of arguments
patrick.greet.apply(patrick, ['Is mayonnaise an instrument?', 'Mayonnaise is not an instrument 😔']);
I think that concludes the differences between the three. Let’s recap everything and draw the conclusion.
Conclusion
- Use
bind
when you want to bind a context to a function you want to call later. - Use
call
orapply
if you want to invoke the function immediately.
And the greatest question of the universe when talking about call
and apply
—
Which one to choose? It really depends on your choice.
Though if we look at which one performs better, it seems that the winner is call.
Top comments (4)
I think it's worth pointing out that you can bind any or all of the arguments, not just 'this'.
e.g.
And that it also works where 'this' doesn't.
Likewise for apply and call.
A lot of coders seem to avoid using these methods according to its complexity and confusing use cases. You obviously made it easy to understand. Thanks.
This is so explanatory, Ferenc. Thanks for writing this piece!
this one is cool, THANK YOU