DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Cover image for this keyword and .call(), .apply(), .bind() method
Nasirul Islam
Nasirul Islam

Posted on

this keyword and .call(), .apply(), .bind() method

What is this keyword in javascript?

"this" keyword in JavaScript allows a function to be re-used in various execution contexts. That is, once a function is defined, it can be invoked for different objects using the "this" keyword. The current execution contact identifies an object when we invoke a method.

If you want to understand this keyword, you have to know some binding rules. We will discuss these step by step.

Implicit Binding

In the case of common JavaScript functions, if the function is preceded by a (.) Dot notation, then the object before the dot notation is the "this" or object inside the function. If the property of the object is not found then JavaScript takes the window as the object by default.

let blog = {
    name: 'Tapas',
    address: 'freecodecamp',
    message: function() {
        console.log(`${this.name} blogs on ${this.address}`);
    }
};

blog.message();

Enter fullscreen mode Exit fullscreen mode

Explicit Binding:

If the function is not within an object, but if the function is in a global context, then when calling the function, it is necessary to specify which object will be "this" directly. This requires some built-in methods of JavaScript. The methods are:

let getName = function() {
     console.log(this.name);
 }

let user = {
   name: 'Tapas',
   address: 'Freecodecamp'  
 };

getName.call(user);

Enter fullscreen mode Exit fullscreen mode

.call() method:

If the function is in the global context, then when invoked the function you have to specify which object will be "this" directly. This requires using JavaScript's built-in method .call(). .call() method takes an object as the first parameter of the method and many more parameters can be given later.

.apply() method:

In the same case, JavaScript's built-in method .apply() can be used. It works like the .call () method. However, the .apply() method takes an object as its first parameter and an array as its second parameter.

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }

let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];

getName.apply(user, hobbies);

Enter fullscreen mode Exit fullscreen mode

.bind() method:

The .bind() method works just like the .call() method. However, the difference is that the .bind() method returns the instance of the function without directly calling the function and we can store it in a variable and call this variable as a function.

let getName = function(hobby1, hobby2) {
     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2);
 }

let user = {
   name: 'Tapas',
   address: 'Bangalore'  
 };

let hobbies = ['Swimming', 'Blogging'];
let newFn = getName.bind(user, hobbies[0], hobbies[1]); 

newFn();

Enter fullscreen mode Exit fullscreen mode

Window Binding:

If "this" is an object within a function, unless it is defined directly or indirectly, JavaScript takes window as the object by default. This is basically window binding.

Conclusion

From this tutorial, we have learned "this" keyword in javascript and .call(), .apply(), .bind() methods.

Reference

Thanks for reading

Reach out to me on:

Top comments (9)

Collapse
 
lukeshiru profile image
Luke Shiru • Edited on

Remember that you can also just not use this at all, and be a happier developer in the process by not needing call, apply or bind πŸ˜„

Click here to see the snippets in this post without using this

First, lest's always use the same user for the examples to avoid repetition:

const user = {
    name: "Tapas",
    address: "Bangalore",
    hobbies: ["Swimming", "Blogging"],
};
Enter fullscreen mode Exit fullscreen mode

Now for the 1st example (internal this usage):

// Take the function away from the object
const logBlog = ({ name, address }) =>
    console.log(`${name} blogs on ${address}`);

// And then there is no need for `this`, just pass user to `logBlog`:
logBlog(user);
Enter fullscreen mode Exit fullscreen mode

The 2nd example (using call):

// Why have a function with no arguments and pass `this`
// when we can just pass the `user` to it?
const logName = ({ name }) => console.log(name);

logName(user);
Enter fullscreen mode Exit fullscreen mode

The 3rd and for 4th are fixed the same way (.call and .apply):

// The user itself includes hobbies
const logNameAndHobbies = ({ name, hobbies }) =>
    console.log(`${name} likes ${hobbies.join(", ")}`);

// And we pass the user to the function like in all the previous examples
logNameAndHobbies(user);
Enter fullscreen mode Exit fullscreen mode

When we don't use this, we write functions that are more explicit about their arguments and we simplify the process a lot because we no longer need all this methods, we keep it consistent.


Cheers!

Collapse
 
activenode profile image
David Lorenz

Hey. I do agree. I also wouldn't recommend the above functions anymore (see my other comment with post reference here).

However I think this article from @nasirulislam is extremely helpful from the perspective of "Understanding JavaScript" as a wholesome piece. The one that knows more also is able to make better decisions. If one doesn't know bind etc. one cannot discuss about it hence also not neglect it for good reasons. So I find it very important that JS developers do know even things that they might decline for good reasons. But you cannot decline something you do not know. And this is also what makes up a good developer: Being able to explain why something shouldn't be used instead of just saying "don't because there is also alternatives".

Collapse
 
lukeshiru profile image
Luke Shiru

Yup, don't get me wrong I'm not saying this isn't useful to know (because it is), is just isn't useful to use 🀣

Collapse
 
pengeszikra profile image
Peter Vivo

You right! I try to coding without this, function and binds of course (it is works!). And that way is much more easier. Because don't need worried about this is where to point. Functional programming so much cleaner than OOP in JS.

Collapse
 
nasirulislam profile image
Nasirul Islam

thanks for inform

Collapse
 
activenode profile image
David Lorenz

Thank you for this article Nasirul πŸ‘Œ

Fun thing that this just popped up in my article list. Because I would like to add the information that with Arrow Functions (related post) all of the above mentioned is not working. This is important to note because it also doesn't throw an error. So calling e.g. bind(someContext) on an arrow function e.g. const func = () => console.log(this); func.bind({ foobar: 'foo'})() will not log the foobar object.

This is an important addendum in the world of arrow-functions being used very often because not knowing it leads to severe bugs in applications that only show up later.

Even worse: If there is a transpiler in between and the arrow function gets converted to a real function then it "seems like" it is also working for arrow functions.

So the following could happen: Say you are developing an enterprise application and you are using bind. Also you are supporting IE11 for some reason so you use transpilation of arrow functions. Now you deploy all of this and everything works fine because the former arrow function is an actual function.

Some time later the corporation says: We switched to Chrome, you can switch of IE11 support. So you do. You turn off compilation and the whole application might break because the context binding suddenly is broken.

Long story short: Be aware of the fact that the mentioned functions shouldn't be used in combination with arrow functions and it's fine.

Collapse
 
nasirulislam profile image
Nasirul Islam

I'm sorry that I forgot to notice such a thing. But at the beginning, I said that it only applies to common functions. That means it won't work to the arrow function. You can see if you notice a little.

Collapse
 
activenode profile image
David Lorenz

Sure Thing. I wasn't downtalking the article, just provided additional info πŸ€—

Thread Thread
 
nasirulislam profile image
Nasirul Islam

thanks for information

Timeless DEV post...

How to write a kickass README

Arguably the single most important piece of documentation for any open source project is the README. A good README not only informs people what the project does and who it is for but also how they use and contribute to it.

If you write a README without sufficient explanation of what your project does or how people can use it then it pretty much defeats the purpose of being open source as other developers are less likely to engage with or contribute towards it.