Understanding Javascript's Call, Apply and Bind Methods

Understanding Javascript's Call, Apply and Bind Methods

When learning Javascript, you will come across the this keyword. The this keyword is associated with Object Oriented Programming (OOP). In JavaScript, the value of this depends on how a function is called, not where the function is declared.

Let’s look at an example to show the behavior of this in JavaScript.

const profile = {
fullName: 'Jon Smith',
birthYear: 1993,
overview: function () { 
    console.log( `My name is ${this.fullName}, I was born in ${this.birthYear}`)
    }
}

Now let's execute the overview method:

profile.overview()

This prints

My name is Jon Smith, I was born in 1993

From the example, this keyword in the overview method refers to the profile object, not because overview is a property of profile , but because we called it directly on profile.

Let's consider what happens if we assign the object to a variable

const printProfile = profile.overview()

Surprisely, this prints

My name is undefined, I was born in undefined

Why?

This is because of the way we called the function, JavaScript didn’t know that the function was declared in profile in the first place , so this was bound to undefined. So we can see that the this keyword inside a function refers to different objects depending on how the function is called.

Call(), Bind() and Apply()

JavaScript provides some special methods and properties to every function object. So those methods are inherited by every function in JavaScript. Some of these methods are call, bind, and apply. These three methods allow you to specify what this is bound to no matter how or where the function in question is called.

Call()

Call() allows us to call a function as if it were a method by providing it an object to bind this to. Call() also accepts a comma-separated list of arguments. The first argument to call is the value you want to bind this to, and any remaining arguments become arguments to the function you’re calling. Consider the following example;

const intro = { fullName: "Clark Kent" };

function sayHello() {
    console.log( `Hello, I'm ${this.fullName}!`);
}

function sayHello2(location) {
    console.log(`Hello, I'm ${this.fullName}, I live in ${location}`);
}

sayHello();
sayHello.call(intro);
sayHello2.call(intro, 'Small view')

This prints

Hello, I'm undefined!

Hello, I'm Clark Kent!

Hello, I'm Clark Kent, I live in Small view

Apply()

The apply() method is identical to call() except it accepts an array of arguments instead of comma separated values. Consider the following example;

const intro = { fullName: "Clark Kent" };

function sayHello(birthYear, location) {
    console.log( `Hello, I'm ${this.fullName}, born in ${birthYear}. I live at ${location}`);
}

sayHello.apply(intro, [1993, "Small view"])

The above example takes in intro object as the first argument and takes the values of an array as other arguments.

Bind()

With bind() method, you can associate the value of this with a function permanently.

const intro = { fullName: "Clark Kent" };

function greeting() {
    console.log(`Hello I am ${this.fullName}`)
}

We can use the bind() method on the greeting function to bind the this keyword to intro object. We also pass in extra arguments. For example:

const updateGreeting = greeting.bind(intro);

updateGreeting();

This prints

Hello I am Clark Kent

Taking in an extra argument:

const intro = { fullName: "Clark Kent" };

function greeting(alterEgo) {
    console.log(`Hello I am ${this.fullName}, you can call me ${alterEgo}!`)
}

const updateGreeting = greeting.bind(intro, 'Superman');

updateGreeting();

This prints

Hello I am Clark Kent, you can call me Superman!

Conclusion

The call, bind and apply methods can be used to set the this keyword not minding how a function is called. The bind() method sets the value of this and makes a copy of the function, while the call() and apply() methods set the this keyword and invokes the function immediately.

And that's a wrap. If you found this article helpful, kindly leave a comment. And if you have any doubt or any tip, feel free to comment as well! I’d be glad to help 😊