call(), apply() and bind() methods in JavaScript

Photo by Dan Bucko on Unsplash

call(), apply() and bind() methods in JavaScript

Hello readers, call, apply and bind methods are the most asked topic in JavaScript interviews as they are popularly used. Before directly heading towards the understanding of call, apply and bind methods, it is important to understand the "this" keyword and what it refers to.

"this" keyword

this refers to the object that is executing the current piece of code.

this.png

The above image depicts the Global execution context, it consists of the following:

  • The global object: - In the browser, this is a window object.
  • "this" keyword: - this is referring to the global object
  • The variable environment: - a place in memory where variables live.
  • The outer environment: -When we execute code within a function the outer environment is the code outside that function — at the global level, it is null.

"this" refers to different objects depending on how it is used:

  • In an object method, this refers to the object.
  • Directly, this refers to the global object.
  • In an event, this refers to the element that received the event.
  • In a function, this refers to the global object.
  • In a function, in strict mode, this is undefined.

For more details, check out mdn docs: developer.mozilla.org/en-US/docs/Web/JavaSc..

Call, Apply and Bind

Call, Apply and Bind are the method in Javascript and basically used to control what this in a function points to. Also called function borrowing methods.

Function borrowing allows us to use the methods defined in one object on a different object without making a copy of the method.

Implicit Binding

In JavaScript, implicit binding is already declared by the language. As shown in the code snippet below.

const fruit = {
  name: "mango",
  printFruit: function () {
    console.log(this.name)  // mango
  }
}
fruit.printFruit()

Explicit Binding

In Explicit Binding, we explicitly point this of function to the object, both defined in the same level of scope.

const fruit = {
  name: "mango",
}

function printFruit() {
    console.log(this.name)  // mango
  }

printFruit.call(fruit)

In the above code snippet, object and function are defined in the global environment, by using the call() method we explicitly point this of the function (printFruit) to the object (fruit).

call() method

In the call() method, the context with which the function has to be called is passed as a parameter to the call.

As shown In the fruit example above.

How to pass multiple parameters in the call() method?

In the same example of fruit, we can pass the arguments to the call method as shown in the snippet below:

Code snippet of the call() method:

const fruit = {
  name: "mango",
}

function printFruit(fruit2, fruit3) {
    console.log(this.name, fruit2, fruit3)  // mango apple banana
  }

printFruit.call(fruit, "apple", "banana")

In the call() method, the first argument is the object with whose context the function is to be called and the following arguments are the values with are to be used in the function.

apply() method

apply() method is the same as the call(), except the second argument is passed as an array of values.

Code snippet of the apply() method:

const fruit = {
  name: "mango",
}

function printFruit(...args) {
    console.log(this.name, args[0], args[1])  // mango apple banana
  }

printFruit.apply(fruit, ["apple", "banana"])

This makes it easier as we need to pass an array as an argument.

bind() method

bind() method is similar to call(), with one difference. Unlike the call() method invoking a function directly, the bind method returns the brand new function which can be stored and invoked as and when required.

Code snippet of the bind() method:

const fruit = {
  name: "mango",
}

function printFruit() {
    console.log(this.name)  // mango 
  }

const storedFunction = printFruit.bind(fruit)

storedFunction()

Here, the printFruit.bind(fruit) return a brand new function, which is stored in storedFunction and invoked on the next line when required.

Summary

  • This keyword refers to different objects depending on how it is used.
  • In the case of implicit binding, this binds to the object adjacent to the dot(.) operator while invoking the method.
  • In the case of explicit binding, we can call a function with an object when the function is outside of the execution context of the object. This can be done using call(), apply() and bind().