Understanding bind(), call() and apply() methods in JavaScript

Understanding bind(), call() and apply() methods in JavaScript

In this article, I briefly discuss the bind(), call() and apply() methods in JavaScript by example

If you are learning JavaScript, you might have seen the this keyword. The this keyword in JavaScript behaves differently compared to other programming languages. This causes a lot of confusion for programmers.

In other object-oriented programming languages, the this keyword always refers to the current instance of the class. Whereas in JavaScript, the value of this depends on how a function is called.

Let’s look at some examples to demonstrate the behavior of this in JavaScript.

Example 1:

const person = {

  firstName: 'John',

  lastName: 'Doe',

  printName: function() {

    console.log(this.firstName + ' ' + this.lastName);

  }

};

Now let’s execute the printName method.

person.printName();

This prints:

John Doe

Here, I am calling the printName() method using the person object, so the this keyword inside the method refers to the person object.

Let’s write the below snippet at the end of the above code.

const printFullName = person.printName;

printFullName();

What do you think the console.log will now output? Surprisingly, this prints:

undefined undefined

Why does this happen?

Here, we are storing a reference of person.printName to printFullName variable. After that, we are calling it without an object reference, so this will now refer to the window (global) object or undefined (in strict mode).

If the script is in strict mode, this refers to undefined, so console.log() will return an error.

Example 2:

const counter = {

  count: 0,

  incrementCounter: function() {

    console.log(this);

    this.count++;

  }

}document.querySelector('.btn').addEventListener('click', counter.incrementCounter);

What would be the value of this inside incrementCounter() method?

In the above snippet, the this keyword refers to the DOM element where the event happened, not the counter object.

So we can see that the this keyword inside a function refers to different objects depending on how the function is called and sometimes we accidentally lose reference to the this variable. So how can we prevent that from happening?

Call( ), Bind( ), and Apply( ) to Rescue

We use call, bind and apply methods to set the this keyword independent of how the function is called. This is especially useful for the callbacks (as in the above example).

We know that functions are a special kind of objects in JavaScript. So they have access to some methods and properties. To prove functions are objects, we can do something like this, for example:

function greeting() {

  console.log('Hello World');

}greeting.lang = 'English';// Prints 'English'

console.log(greeting.lang);

JavaScript also provides some special methods and properties to every function object. So every function in JavaScript inherits those methods. Call, bind, and apply are some of the methods that every function inherits.

Bind( )

The bind method creates a new function and sets the this keyword to the specified object.

Syntax:

function.bind(thisArg, optionalArguments)

For example:

Let’s suppose we have two person objects.

const john = {

  name: 'John',

  age: 24,

};const jane = {

  name: 'Jane',

  age: 22,

};

Let’s add a greeting function:

function greeting() {

  console.log(Hi, I am ${this.name} and I am ${this.age} years old);

}

We can use the bind method on the greeting function to bind the this keyword to john and jane objects. For example:

const greetingJohn = greeting.bind(john);// Hi, I am John and I am 24 years old

greetingJohn();const greetingJane = greeting.bind(jane);// Hi, I am Jane and I am 22 years old

greetingJane();

Here greeting.bind(john) creates a new function with this set to john object, which we then assign to greetingJohn variable. Similarly for greetingJane.

We can also use bind in case of callbacks and event handlers. For example:

const counter = {

  count: 0,

  incrementCounter: function() {

    console.log(this);

    this.count++;

  }

}document.querySelector('.btn').addEventListener('click', counter.incrementCounter.bind(counter));

In the above example, the this keyword inside the incrementCounter method will now correctly refer to the counter object instead of the event object.

Bind() can also accept arguments

We can also pass extra arguments to the bind method. The general syntax for this is function.bind(this, arg1, arg2, ...). For example:

function greeting(lang) {

  console.log(${lang}: I am ${this.name});

}const john = {

  name: 'John'

};const jane = {

  name: 'Jane'

};const greetingJohn = greeting.bind(john, 'en');

greetingJohn();const greetingJane = greeting.bind(jane, 'es');

greetingJane();

In the above example, the bind method creates a new function with certain parameters predefined (lang in this case) and this keyword set to the john and jane objects.

Call ( )

The call method sets the this inside the function and immediately executes that function.

The difference between call() and bind() is that the call() sets the this keyword and executes the function immediately and it does not create a new copy of the function, while the bind() creates a copy of that function and sets the this keyword.

Syntax:

function.call(thisArg, arg1, agr2, ...)

For example:

function greeting() {

  console.log(Hi, I am ${this.name} and I am ${this.age} years old);

}const john = {

  name: 'John',

  age: 24,

};const jane = {

  name: 'Jane',

  age: 22,

};// Hi, I am John and I am 24 years old

greeting.call(john);// Hi, I am Jane and I am 22 years old

greeting.call(jane);

Above example is similar to the bind() example except that call() does not create a new function. We are directly setting the this keyword using call().

Call () can also accept arguments

Call() also accepts a comma-separated list of arguments. The general syntax for this is function.call(this, arg1, arg2, ...)

For example:

function greet(greeting) {

  console.log(${greeting}, I am ${this.name} and I am ${this.age} years old);

}const john = {

  name: 'John',

  age: 24,

};const jane = {

  name: 'Jane',

  age: 22,

};// Hi, I am John and I am 24 years old

greet.call(john, 'Hi');// Hi, I am Jane and I am 22 years old

greet.call(jane, 'Hello');

Apply ( )

The apply() method is similar to call(). The difference is that the apply() method accepts an array of arguments instead of comma separated values.

Syntax:

function.apply(thisArg, [argumentsArr])

For example:

function greet(greeting, lang) {

  console.log(lang);

  console.log(${greeting}, I am ${this.name} and I am ${this.age} years old);

}const john = {

  name: 'John',

  age: 24,

};const jane = {

  name: 'Jane',

  age: 22,

};// Hi, I am John and I am 24 years old

greet.apply(john, ['Hi', 'en']);// Hi, I am Jane and I am 22 years old

greet.apply(jane, ['Hola', 'es']);

Conclusion

We have learned that how this keyword behaves differently in JavaScript than in other object-oriented languages. The call, bind and apply methods can be used to set the this keyword independent of how a function is called.

The bind method creates a copy of the function and sets the this keyword, while the call and apply methods sets the this keyword and calls the function immediately.

Thanks for reading

If you liked this post, please do share/like it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about JavaScript

The Complete JavaScript Course 2019: Build Real Projects!

Vue JS 2 - The Complete Guide (incl. Vue Router & Vuex)

JavaScript Bootcamp - Build Real World Applications

The Web Developer Bootcamp

JavaScript Programming Tutorial - Full JavaScript Course for Beginners

New ES2019 Features Every JavaScript Developer Should Know

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

What JavaScript Framework You Should Learn to Get a Job in 2019?

Best JavaScript Frameworks, Libraries and Tools to Use in 2019

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Ember.js vs Vue.js - Which is JavaScript Framework Works Better for You

Do we still need JavaScript frameworks?


javascript web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Why Web Development is Important for your Business

With the rapid development in technology, the old ways to do business have changed completely. A lot more advanced and developed ways are ...

Important Reasons to Hire a Professional Web Development Company

    You name the business and I will tell you how web development can help you promote your business. If it is a startup or you seeking some...

Hire Dedicated eCommerce Web Developers | Top eCommerce Web Designers

Build your eCommerce project by hiring our expert eCommerce Website developers. Our Dedicated Web Designers develop powerful & robust website in a short span of time.

How long does it take to develop/build an app?

This article covers A-Z about the mobile and web app development process and answers your question on how long does it take to develop/build an app.

Progressive Web App Development

Hire Full Stack Developer from HireFullStackDeveloperIndia.com to build user-centric & robust Progress Web App Development Solutions in India.