Bind, Call and Apply

  1. Bind Method
    In JavaScript, bind function is used to enhance the implementation of an existing function for that object by creating new function without modifying the original function.
    The bind method does not immediately invoke the function; instead, it returns a new function with the specified this value and optionally initial arguments.

     // Example object
     const person = {
       firstName: "John",
       lastName: "Doe",
       getFullName: function() {
         return this.firstName + " " + this.lastName;
       }
     };
    
     // Create a new function with a specific 'this' value
     const getFullNameFunction = person.getFullName.bind(person);
     // Call the new function
     console.log(getFullNameFunction()); // Outputs: John Doe
    
     const personTwo = {
       firstName: "Michael",
       lastName: "Jorden"
     };
     // Create a new function with a specific 'this' value
     const getFullNameFunctionTwo = person.getFullName.bind(personTwo);
     // Call the new function
     console.log(getFullNameFunctionTwo()); // Outputs: Michael Jorden
    

    In this example, bind is used to create a new function getFullNameFunction where this is bound to the person object. When you later call getFullNameFunction(), it uses the this context of the person object.
    You can bind another object personTwo to get the different result in getFullNameFunctionTwo()
    You can also pass arguments to bind to pre-set initial values for the parameters,

     const greet = function(greeting) {
       return `${greeting}, ${this.firstName} ${this.lastName}!`;
     };
    
     const greetJohn = greet.bind(person, "Hello");
     console.log(greetJohn()); // Outputs: Hello, John Doe!
    

    Here, the greet function is bound to the person object, and the first argument is set to "Hello." When greetJohn() is called, it uses the bound context and the pre-set argument.

    Keep in mind that the original function (getFullName or greet in the examples) is not modified by bind. Instead, bind creates a new function with the specified context and, if provided, initial arguments.

  2. Call Method
    In JavaScript, you can use the call method to invoke a function with a specified this value and arguments provided individually. The basic syntax is as follows,

     function functionName(arg1, arg2, arg3, ...) {
         // function implementation
     }
     // Using call method
     functionName.call(thisValue, arg1, arg2, arg3, ...);
    

    Here, thisValue is the value that will be used as this when the function is executed. The subsequent arguments are the arguments that will be passed to the function.

    Here's a simple example,

     function greet(name) {
         console.log(`Hello, ${name}! I'm ${this.title}.`);
     }
    
     const person = {
         title: 'Mr.'
     };
    
     // Using call method to invoke greet with person as thisValue
     greet.call(person, 'John');
    

    In this example, this.title inside the greet function will refer to the title property of the person object because we used the call method to set the this value.

    Note that the call method is just one of several ways to change the context (this value) of a function in JavaScript. You can also use apply, bind, or the arrow function syntax, depending on your requirements and preferences.

  3. Apply Method
    In JavaScript, the apply method is similar to call but takes an array or array-like object as its second argument, which will be used as the arguments when invoking the function. The basic syntax is as follows,

     function functionName(arg1, arg2, arg3, ...) {
         // function implementation
     }
     // Using apply method
     functionName.apply(thisValue, [arg1, arg2, arg3, ...]);
    

    Here's an example,

     function greet(name, age) {
         console.log(`Hello, ${name}! I'm ${this.title}. I'm ${age} years old.`);
     }
    
     const person = {
         title: 'Mr.'
     };
    
     // Using apply method to invoke greet with person as thisValue and an array of arguments
     greet.apply(person, ['John', 30]);
    

    In this example, this.title inside the greet function will refer to the title property of the person object because we used the apply method to set the this value, and the array ['John', 30] is passed as the arguments.

    Similar to call, the apply method is less commonly used in modern JavaScript, and you might find that using the spread operator (...) with the call method or other alternatives is more common.

  4. Difference between Bind, Call and Apply
    In JavaScript, bind, call, and apply are methods used to control the this context of functions. They all allow you to set the value of this inside a function, but they differ in how they are used and what they return.
    i) Call
    The call method calls a function with a given this value and arguments provided individually.

     // Syntax
     functionName.call(thisArg, arg1, arg2, ...)
    
     // Example
     function greet(greeting, punctuation) {
       console.log(greeting + ', ' + this.name + punctuation);
     }
    
     const person = { name: 'Alice' };
     greet.call(person, 'Hello', '!');
     // Output : Hello, Alice!
    

    ii) Apply
    The apply method is similar to call, but it takes an array (or an array-like object) of arguments instead of listing them one by one.

     // Syntax
     functionName.apply(thisArg, [argsArray])
    
     // Example
     function greet(greeting, punctuation) {
       console.log(greeting + ', ' + this.name + punctuation);
     }
    
     const person = { name: 'Alice' };
     greet.apply(person, ['Hello', '!']);
     // Output : Hello, Alice!
    

    iii) Bind
    The bind method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

     // Syntax
     function.bind(thisArg, arg1, arg2, ...)
    
     // Example
     function greet(greeting, punctuation) {
       console.log(greeting + ', ' + this.name + punctuation);
     }
    
     const person = { name: 'Alice' };
     const greetPerson = greet.bind(person, 'Hello');
     greetPerson('!');
     // Output : Hello, Alice!
    

    iv) Key Differences
    Invocation -
    call immediately invokes the function with the specified this value and arguments.

    apply immediately invokes the function with the specified this value and an array of arguments.

    bind returns a new function with the specified this value and initial arguments, but does not immediately invoke the function.

    Argument Handling -

    call takes arguments as a comma-separated list.

    apply takes arguments as an array.

    bind takes arguments as a comma-separated list, which can be followed by additional arguments when the new function is called.
    When to use what -
    Use call when you want to invoke the function immediately with a specific this value and individual arguments.

    Use apply when you want to invoke the function immediately with a specific this value and an array of arguments.

    Use bind when you want to create a new function with a specific this value and possibly some initial arguments, to be invoked later.