loading...
Cover image for Understanding Bind, Call and Apply in JavaScript

Understanding Bind, Call and Apply in JavaScript

flowforfrank profile image Ferenc Almasi Originally published at webtips.dev ・3 min read

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 or apply 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.


Visit webtips.dev

Discussion

pic
Editor guide
Collapse
pentacular profile image
pentacular

I think it's worth pointing out that you can bind any or all of the arguments, not just 'this'.

e.g.

const context = {};
function setName(name) {
  this.name = name;
}
const setContextNameToFred = setName.bind(context, 'fred');
setContextNameToFred();
console.log(context);
// { name: "fred" }

And that it also works where 'this' doesn't.

const add = (a, b) => a + b;
const addOne = add.bind(null, 1);
console.log(addOne(2));
// 3

Likewise for apply and call.

Collapse
davidyaonz profile image
David Yao

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.

Collapse
calebdeji profile image
calebdeji

This is so explanatory, Ferenc. Thanks for writing this piece!

Collapse
deta19 profile image
mihai

this one is cool, THANK YOU