Understanding Call, Apply and Bind method in Javascript and their uses.

The Call, Apply, and Bind method are very useful. But a lot of us don't use them to their potential simply because we don't understand it. So what exactly are they? When can we use them and how do we know when to use each one? Let's start by understanding why they exist.

Dominos, a very successful pizzeria wants to know the average amount of money they earn in a week. That's where you come in, you create this object with a very useful method. Just to refresh your memory, a method is a function that is called within an object. And in JavaScript, everything is an object including a function!

const dominoes = {
  name: 'Dominos',
  dailyEarnings: [2300, 1900, 3000, 1000, 4000, 4920, 9828],
  calcAverageEarning(earnings = this.dailyEarnings) {
    let sum = 0;
    for (let i = 0; i < earnings.length; i++) {
      sum += earnings[i];
    }
    this.average = Math.round(sum / earnings.length);
    return this.average;
  },
};

Let me explain what's going on in this code. Here we have an object that contains details about dominoes, their name, the money they earn daily stored in an array and a method that calculates the average amount of money they earn in a week. The method has a default parameter that uses the dailyEarnings property if no value is passed to the function.

Just to jog your memory before we go deeper, the this keyword in a method references the current object where it is being called. So in this case, this.dailyEarnings is the same thing as writing dominoes.dailyEarnings. But it's better to use the this keyword just in case we decide to change the variable name of the object, we don't have to rewrite it in every instance that it was mentioned. We also create a new property average that was not previously defined in our dominoes object and set the average value to it.

Dominos is very pleased with you for your work, and it becomes a success. Other restaurant chains are seeing how successful and smart your application is, they decide to hire you to do the same thing for their business. They have their own objects, but you don't want to repeat yourself by defining a new method for every single restaurant that you're working for. You want to reuse your method for dominoes for the other restaurants as well since it's the same formula.

What do you do in this situation?

That's where the call method comes in!

The Call method.

The call method allows us to reuse our calcAverageEarning method in different objects by allowing us to set our own this property which would be the object that we pass to it. Let's say we have another pizza chain that we have to calculate their average earning for, with it's own object.

const galaxyPizza = {
  name: 'Galaxy Pizza',
  dailyEarnings: [500, 900, 1300, 210, 700, 400],
};

We want to reuse the calcAverageEarning method to calculate the average earning that galaxy pizza makes in a week. If we try to use it like this.

const earnings = dominoes.calcAverageEarning;
earnings();

What do you think we'd get as the result? We get the error, Cannot read properties of undefined on the this.dailyEarnings array. that's because the this keyword in a method refers to the current object where it is being called. So we can't call our method this way because there is no longer a dominoes.dailyEarnings property. That is when the call method comes in handy.

const earnings = dominoes.calcAverageEarning;
earnings.call(galaxyPizza);

The call method allows us to set our own this keyword (and in this case, it's the object galaxyPizza). When we log the galaxyPizza object, we see that it now has the property average with a value assigned to it, and we no longer get the undefined error.

Call accepts arguments.

The call method also allows you to call a method with arguments too. The syntax is call(thisArg, arg1, /* …, */ argN) For example, we want to call our method calcAverage method but with different values for dailyEarnings. Remember that calcAverageEarning is a function that accepts an array parameter called earnings. So we can also call the method in this way.

const arr = [200, 1200, 2135, 500, 1000, 600, 800];
const earnings = dominoes.calcAverageEarning;
earnings.call(galaxyPizza, arr);

It will work the same way, except this time we're passing in our own earnings value rather than using the default one from the object because the call method allows for you to pass in arguments too.

The Apply Method.

The Apply method does the same job that call does, except it accepts an array of arguments instead with this syntax apply(thisArg, argsArray)

Let's modify our calcAverageEarning method to accept an additional parameter called name.

const dominoes = {
  name: 'Dominos',
  dailyEarnings: [2300, 1900, 3000, 1000, 4000, 4920, 9828],
  calcAverageEarning(
    earnings = this.dailyEarnings,
    restuarantName = this.name
  ) {
    let sum = 0;
    for (let i = 0; i < earnings.length; i++) {
      sum += earnings[i];
    }
    this.average = `The average ${restuarantName} earns in a week is ${Math.round(
      sum / earnings.length
    )}`;
    return this.average;
  },
};

Hence, we can use the apply method this way

earnings.apply(galaxyPizza, [arr, 'Galaxy Pizza']);

With the first argument being the array we defined earlier, and the second argument being the name of the restaurant.

The Bind Method.

The bind method also works like the call and apply method with the syntax bind(thisArg, arg1, arg2, /* …, */ argN). The difference is bind returns a new function and does not immediately call the function.

const galaxyPizzaEarnings = earnings.bind(galaxyPizza);
galaxyPizzaEarnings();

Bind also accepts arguments.

Conclusion.

We've learnt how the call, bind and apply methods can call methods from another object by manually setting our this keyword to it. We can also pass arguments through them and we've learnt that call and bind accepts arguments seperated by commas and applyaccepts an array of arguments.

The difference between call, apply and bind is that call and apply calls the function instantly while bind returns a new function that's a copy of the method.

If you've found this article useful, make sure to like, comment and follow me! If you have any questions as well feel free to reach out to me for further clarification 🫶🏾.