DEV Community

Cover image for What is call, apply, and bind in JavaScript?
Tomohiro Yoshida
Tomohiro Yoshida

Posted on • Edited on

What is call, apply, and bind in JavaScript?

Do you know how to use Function.call(), Function.apply(), and Function.bind()?

These methods are used to control what the this keyword refers to in a function.

Function.call()

The call() method is explained in MDN below:

The call() method calls the function with a given this value and arguments provided individually.

The syntax of the method is:

call(thisArg)
call(thisArg, arg1)
call(thisArg, arg1, /* …, */ argN)
Enter fullscreen mode Exit fullscreen mode

Here is an example code to see what this refers to without call().

const message = "Hello from window!";

function test() {
    console.log(this.message);
};

test();
// [LOG] Hello from window!
Enter fullscreen mode Exit fullscreen mode

If we do not use call(), this in the test function refers to the global window object. Therefore, the console.log() in the function displays the message, "Hello from window!".

Note: If it was an object method, this refers to the object.

Next, let's see what happens when using call().

const message = "Hello from window!";

const testObj = {
  message: "Hello from testObj!"
};

function test() {
    console.log(this.message);
};

test.call(testObj);
// [LOG] Hello from testObj!
Enter fullscreen mode Exit fullscreen mode

As you can see, this refers to the testObj object when we execute the test function by the call() method with the argument of testObj. It means the this keyword in the function considers testObj as this.

What if the function requires arguments?

If a function requires arguments, you can execute the function with arguments like below:

const testObj = {
  message: "Hello from testObj!"
}

function test(arg1, arg2, arg3) {
  console.log(this.message);
  console.log("arg1: ", arg1, " arg2: ", arg2, " arg3: ", arg3);
}

test.call(testObj, 1, 2, 3);
// [LOG] Hello from testObj!
// [LOG] arg1: 1 arg2: 2 arg3: 3
Enter fullscreen mode Exit fullscreen mode

Function.apply()

The apply() method works similarly to the call() method. But the only difference is the apply() method receives an array of the original function's arguments as an argument.

The syntax of the method is:

apply(thisArg)
apply(thisArg, argsArray)
Enter fullscreen mode Exit fullscreen mode

If you want to execute the test function by the apply() method, the code will be like this:

const testObj = {
  message: "Hello from testObj!"
}

function test(arg1, arg2, arg3) {
  console.log(this.message);
  console.log("arg1: ", arg1, " arg2: ", arg2, " arg3: ", arg3);
}

test.apply(testObj, [1, 2, 3]);
// [LOG] Hello from testObj!
// [LOG] arg1: 1 arg2: 2 arg3: 3
Enter fullscreen mode Exit fullscreen mode

Cool! We can get the same outcome as the previous example code.

Function.bind()

The bind() method works differently compared with the other two methods.
This method returns a copy of the function with provided arguments instead of executing the function immediately.

The syntax of the method is:

bind(thisArg)
bind(thisArg, arg1)
bind(thisArg, arg1, arg2)
bind(thisArg, arg1, arg2, /* …, */ argN)
Enter fullscreen mode Exit fullscreen mode

As with the call() method, the bind() method will receive a value that will be a target of this and a number of arguments that will be provided to the original function.

If you want to use the bind() method with the test function, which we used above, the code will be below:

const testObj = {
  message: "Hello from testObj!"
}

function test(arg1, arg2, arg3) {
  console.log(this.message);
  console.log("arg1: ", arg1, " arg2: ", arg2, " arg3: ", arg3);
}

const boundTestFunc = test.bind(testObj, 1, 2, 3);

boundTestFunc();
// [LOG] Hello from testObj!
// [LOG] arg1: 1 arg2: 2 arg3: 3
Enter fullscreen mode Exit fullscreen mode

As you saw, we could get the same log results as the call() method. However, you need to execute the new function after making a copy of the original one, like boundTestFunc() if you want to call it.

What is the actual use case?

You may wonder when we use the methods in real-world development. I would honestly say that we do not frequently use these methods on a daily basis.
But, let me share one of the common use cases of the bind() method in modern web development.

You will see a code like the one below if you are assigned to work on refactoring the React.js project written with the Class components.

class ExampleComponent extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: '' };
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  render() {
    return (
      <input
        type="text"
        value={this.state.value}
        onChange={this.handleChange.bind(this)}
      />
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The bind() method is used when passing the handleChange method to onChange of the input element. This is because when calling the method as an event handler in Class components of React.js, this will be undefined. (this should have referred to the object if the this keyword is used in methods of the object.)

But, considering recent React.js projects, Functional components are used more often than Class components. Thus, you rarely see Class components and the bind() method accordingly, even in React.js projects, unless you are assigned to legacy code maintenance or refactoring.

Summary

The three methods, Function.call(), Function.apply(), and Function.bind(), are used to control where the this keyword refers to.
The call() and apply() methods are used to immediately execute a function with a certain this and arguments. These are used for very similar purposes.
On the other hand, the bind() method is used to create a new function, and that was commonly used in Class components in React.js project.

Top comments (0)