Unveiling the Secrets of JavaScript's call(), apply(), and bind() Methods.

Unveiling the Secrets of JavaScript's call(), apply(), and bind() Methods.

·

4 min read

Introduction:

JavaScript's function manipulation capabilities are taken to new heights with the call(), apply(), and bind() methods. In this comprehensive blog post, we'll delve into the intricacies of each method, explore their distinct use cases, and even cover how to polyfill the bind() method for older browsers. By mastering these methods, you'll gain a powerful toolkit to dynamically control function behavior in your JavaScript applications.

1. call() Method:

  • The call() method allows you to invoke a function explicitly, specifying both the execution context and individual arguments. The syntax for call() is as follows:
//Syntax
function.call(this, arg1, arg2,....)

//functionName: The function to be invoked.
//this: The value to be passed as the execution context.
//arg1, arg2, ...: Arguments to be passed to the function individually.
  • The call() method returns the result of invoking the function with the specified context and arguments.
function greet(message) {
  console.log(`${message}, ${this.name}!`);
}
const person = { name: "John" };
//using object (person) in place of this
console.log(greet.call(person, "Hello")); //Hello, John!

function sum(a, b) {
  return a + b;
}
//We want to simply call this function like sum(5,3).
console.log(sum.call(this, 5, 3));//8
console.log(sum.call(5,3)); //NaN

2. apply() Method:

The apply() method in JavaScript is closely related to the call() method and provides another way to invoke a function with a specific execution context. While call() accepts arguments individually, apply() accepts an array or an array-like object as its second argument, allowing you to pass multiple arguments to the function. Here's an overview of the apply() method:

  • Syntax: The apply() method can take two parameters
functionName.apply(thisArg, [argsArray]);

//functionName: The function to be invoked.
//thisArg: The value to be passed as the execution context within the function.
//argsArray: An array or array-like object containing the arguments to be passed to the function.
  • The apply() method returns the result of invoking the function with the specified context and arguments.
const personName = {
  firstName: "Taylor",
  lastName: "Jackson",
};

function greet(wish, message) {
  return `${this.firstName}, ${wish}. ${message}`;
}
// calling greet() function by passing two arguments
let result = greet.apply(personName, ["Good morning", "How are you?"]);
console.log(result);

//Taylor, Good morning. How are you?
  • apply() to Append two Arrays
let color1 = ["Red", "Green", "Blue"];
let color2 = ["Yellow", "Black"];

// appending two arrays color1 and color2
Array.prototype.push.apply(color2, color1);
console.log(color2);
//[ 'Yellow', 'Black', 'Red', 'Green', 'Blue' ]

3. bind() Method:

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

The syntax of the bind() method is:

func.bind(thisArg, arg1, ... argN)
  • Returns a copy of the given function with the specified this value, and initial arguments (if provided).

      const student1 = {
        name: "Jack",
        introduction: function (score) {
          console.log(this.name + "scored " + score + " in an exam.");
        },
      };
    
      const student2 = {
        name: "Jimmy "
      };
    
      let result = student1.introduction.bind(student2, 95);
      result(); // Jimmy scored 95 in an exam.
    
    • The returned function from bind() doesn't immediately execute; rather, it awaits invocation.

Polyfilling the bind() Method:

In some older browsers, the bind() method may not be supported. However, you can create a polyfill to overcome this limitation. Here's an example of a bind() polyfill:

if (!Function.prototype.bind) {
    Function.prototype.bind = function (...args) {
        let obj = this,
            params = args.slice(1);
        return function (...args2) {
            obj.apply(args[0], [...params, ...args2]);
        }
    }
}

This polyfill checks if the bind() method is not available and then defines it using the apply() method. It captures the original function (this) and the context, binds them together, and returns a new function with the specified arguments.

Conclusion:

Understanding the nuances of call(), apply(), and bind() methods empowers JavaScript developers to control function execution and behavior dynamically. Each method serves a distinct purpose, catering to different scenarios in function manipulation. By mastering these methods and having a polyfill for bind() in your toolbox, you'll be well-equipped to tackle complex scenarios and build robust JavaScript applications.

Unlock the full potential of function manipulation in your code with call(), apply(), and bind() methods, and embrace the limitless possibilities they offer!