Skip to main content

Command Palette

Search for a command to run...

Understanding Call, Apply, and Bind Methods in JavaScript

Updated
4 min read

Before understanding the call, apply, and bind methods, it is essential to understand the concept of the this keyword in JavaScript. The this keyword refers to the context in which a function is executing. Its value is not fixed and depends on how a function is invoked. Understanding the this keyword enables developers to write flexible and reusable code, as functions can operate in different contexts depending on their invocation.

The value of this is determined at runtime based on how a function is called. This dynamic binding allows functions to operate on various objects without requiring them to be rewritten. For instance, a method defined on one object can be invoked on another object, promoting code reuse and modularity.

function name(){
    console.log(this);
}

let obj = {
    name: "alok",
    printName: function (){
        console.log(this);
    }
}

name()
obj.printName()

"use strict"
function name(){
    console.log(this);
}

name()
window.name()

As you can see, the value of this depends on how the function is invoked and also on the use of strict mode. It behaves differently for arrow functions and normal functions. We can use the value of the this keyword to write more efficient and modular JavaScript functions.

Why to use call, apply and bind methods

In JavaScript, whenever we want to control the context in which our function is executing, we can use these three methods (call, apply, bind) which are present in the prototype of the function (Function.prototype).

Call ( ) Method

The call method in JavaScript is a predefined method in the function prototype. This method allows us to call a function with an arbitrary this value and provided arguments without first attaching the function to the object as a property. In simple words, you can call a function and also specify the context in which you want to execute it.

Syntax:
call(this)
call(this, ...args)  // ...args is comma separated values of arguments
Example:
let myName = {
    name: "alok",
}

let myName2 = {
    name: "abhay",
}

function greet(){
    console.log(`Hello, ${this.name}`)
}

greet.call(myName) // Hello, alok
greet.call(myName2) // Hello, abhay

// With Arguments
let myName = {
    name: "alok",
}

let myName2 = {
    name: "abhay",
}

function greet(msg, day){
    console.log(`Hello, ${this.name} - ${msg}. Today is ${day}`)
}

greet.call(myName,"Good Morning","Wednesday")
greet.call(myName2,"Good evening","Friday")

If we don’t provide any arguments to the call function, it will still execute, but the value of this will be either undefined or the global object, depending on the use of strict mode or non-strict mode.

Apply ( ) Method

Apply does the same work as the call function does, but the difference is that apply takes the function arguments as a list of values rather than comma-separated values as the call function does.

Syntax:
apply(this)
apply(this, [arg1, arg2, arg3, ...... ,argN])
Example:
let myName = {
    firstName: "alok",
    lastName: "raturi",
    printName:function(msg, day){
        console.log(`Hello, ${this.firstName} ${this.lastName}- ${msg}. Today is ${day}`);
    }
}

let myName2 = {
    firstName: "abhay",
    lastName: "singh",
}

myName.printName.apply(myName2, ['Good Morning',"Wednesday"]);
myName.printName.call(myName2, 'Good Morning',"Wednesday");

As you can see, invoking the printName function by call and apply methods gives the same output; only the syntax is different. You can use call and apply interchangeably, but you have to be careful with the syntax.

Function borrowing: Using methods like call, apply, and bind, we can use the function associated with a specific object to be called by another object without rewriting the function. For example, in the above example, the myName2 object is also using the printName function, which is in the myName object..

Bind ( ) Method

Bind is another function provided in the function prototype (Function.prototype). It returns a new function with the specified this value, which can be called later at any point in our program. The set of arguments required for the function can be provided with the bind function itself, or we can give them to the new function when we invoke it later.

Syntax:
bind(this)
bind(this, ...args)  // comma separated values of arguments

Example:

let myName = {
    firstName: "alok",
    lastName: "raturi",
    printName:function(msg, day){
        console.log(`Hello, ${this.firstName} ${this.lastName}- ${msg}. Today is ${day}`);
    }
}

let myName2 = {
    firstName: "abhay",
    lastName: "singh",
}


function SayHi(){
    console.log(`Hi, ${this.firstName}`);
}

let sayHi1 = SayHi.bind(myName);
let sayHi2 = SayHi.bind(myName2);
let printName  = myName.printName.bind(myName2, "Good morning","Tuesday")

sayHi1()
sayHi2()
printName()

Conclusion

The call, apply, and bind methods in JavaScript are essential functions that every JavaScript programmer should know to ensure code reusability and maintainability. By leveraging these methods, developers can write cleaner, more modular code that adheres to best practices.

Thank you for your time! Please let me know if there are any opportunities for improvement in this blog or any additions I can make in the comment section.

A

Really Helpful :)