15. Function borrowing - call , apply , bind

Function borrowing allows us to use the methods of one object on a different object without having to make a copy of that method and maintain it in two separate places

It is accomplished through the use of .call(), .apply(), or .bind(), all of which exist to explicitly set this on the method we are borrowing.

Example:

const person1 = {
    name: "Alice",
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

const person2 = { 
    name: "Bob" ,
   };

// Borrowing greet() from person1
person1.greet.call(person2); // Output: "Hello, my name is Bob"
  1. call()

    » The call() method immediately invokes a function and allows us to pass arguments one by one.

    » Syntax: functionName.call(object, arg1, arg2, ...);

     function introduce(role) {
         console.log(`Hi, I am ${this.name} and I am a ${role}.`);
     }
    
     const person = { name: "Charlie" };
    
     introduce.call(person, "developer"); // Output: "Hi, I am Charlie and I am a developer."
    
  1. apply()

    » The apply() method is similar to call(), but it takes arguments as an array instead of individual values.

    » Syntax: functionName.apply(object, [arg1, arg2, ...]);

     function introduce(role, country) {
         console.log(`Hi, I am ${this.name}, a ${role} from ${country}.`);
     }
    
     const person = { name: "David" };
    
     introduce.apply(person, ["teacher", "USA"]); 
     // Output: "Hi, I am David, a teacher from USA."
    
  1. bind()
  • The bind() method does not immediately invoke the function.

  • It returns a new function with the specified this value, which can be called later.

  • Syntax: let newFunc = functionName.bind(object, arg1, arg2, ...);

      function introduce(role) {
          console.log(`Hi, I am ${this.name} and I am a ${role}.`);
      }
    
      const person = { name: "Emily" };
    
      const boundFunc = introduce.bind(person, "designer");
      boundFunc(); // Output: "Hi, I am Emily and I am a designer."
    

    Unlike call() and apply(), bind() does not execute the function immediately. we need to store or bound it in other variable.

  1. Important Example :

     const car = {
         brand: "Toyota",
         showBrand: function() {
             console.log(`Car brand: ${this.brand}`);
         }
     };
    
     const bike = { brand: "Honda" };
    
     // Borrowing the function
     car.showBrand.call(bike); // Output: "Car brand: Honda"
    
     const boundFunc = car.showBrand.bind(bike);
     boundFunc(); // Output: "Car brand: Honda"
    

Interview Questions

  1. Diffrence between call , apply , bind ?
call()Execute immediatelypassed indivduallyreturns : undefined (no new function)
apply()Execute immediatelypassed as an arrayreturns : undefined (no new function)
bind()Does not execute immediatelypassed individuallyReturns a new function
  1. What will be the output of the following code?

     const person = { name: "Michael" };
    
     function greet() {
         console.log(`Hello, ${this.name}`);
     }
    
     const boundFunc = greet.bind(person);
     boundFunc();
    
    • bind() returns a new function, so boundFunc() is called later.

    • Output: "Hello, Michael"

  1. How do you borrow a method from an array?

    You can use call() or apply() to borrow array methods.

     const person = { name: "Sam" };
     const arr = ["A", "B", "C"];
    
     console.log(Array.prototype.join.call(arr, "-")); 
     // Output: "A-B-C"
    

    Here, join() is borrowed from Array.prototype and applied to arr.