Learn "this" Keyword, Once and Forever
Tags: javascript, react, vue, angular
Published: 2020-07-29 06:44:55

As a javascript developer, whether you are writing vanilla(pure) js, creating the next "React" yourself, or working with Vue, Angular, Svelte, or any other framework/library, you need to know this well.
As I talk to other developers, I sometimes notice that there is a big hole in their understanding of this. so I'm here to mention some of them and make you and `this` good friends forever :)

---

Let's dive into some examples to start learning what this is and how it's used.

![logThis function](https://dev-to-uploads.s3.amazonaws.com/i/ci65qsxvvks6jjdfn1nr.png)

Assume we wrote `logThis`.
What if we call it? what is the value of this?
So, the truth is, it depends :) like any other question.
on what? let me explain:
we can call a function in a number of ways,
1. Invoking it normally, like `logThis()`,
2. Set it as a method of an object and then call it like `obj.logThis()`,
3. With the use of `.call`, `.apply` or `.bind`
4. And finally, calling it with new, like `new LogThis()`.

Here is a rule of thumb:
**How you call a function determines what `this` is**.
Let's discuss it further.

1. normal invocation with `()`
in this case, the answer is `global` object, which is `window` in Browser global in Node. just to mention, there is a subtle point. if we're in strict mode the answer to example 1, is always undefined.
Let's go to the next case,


2\. calling a function as a method of an object, `x.y()`

![as a method](https://dev-to-uploads.s3.amazonaws.com/i/m3yeb91tv6ey4u19ylph.png)
It's all about **how** we call the function
As we can see in the example above, there is no difference in how we assigned the method to our objects. the value of this depends on how we call that function, nothing more. when we call a function like `x.y.z()`, this will be `x.y`.
You might ask what if we have a method in an obj, and then we assign it to a variable and then calling that new function.

![this in a method](https://dev-to-uploads.s3.amazonaws.com/i/7aqnk5n1jun4zwqejbqx.png)
As you see, the thing is "all that's important, is how function calls are written".


3\. Using `call`, `apply` or `bind`
generally speaking, bind, call, and apply are used to change the `this` of a function. the context that a function will has when it's running.
but there is a subtle difference between bind and call/apply.
bind, returns a new function, with the this we assigned; in contrast, call and apply will not return a new function but will call the original function with our desired this and then return the invocation result.
So, now we know how `call`, `apply`, and `bind` work.
Let's talk about this value in each one.

![changing the value of this](https://dev-to-uploads.s3.amazonaws.com/i/c44839m6g3i9548kt3aa.png)
As we can see, we can change the context of a function both when we want to call it immediately(by call and apply), and when we want to call it later(by bind).
Keep in mind that whenever we use bind, we are creating a function that we never can change it's `this`, except when we call this function by `new`.


4\. And finally, calling a function with new
The new keyword is a strong one. it rules over all of the above cases when we are talking about this.
Whenever a function is called with new, regardless of how it's written, the function starts to run with a `this` equal to an empty object.
if we don't return this, it's returned automatically. but another point is if we return any object other than this, then this will not get returned and that object will, instead. any primitive value(like string, number, null, …) returned will be ignored and results `this` to be returned.


---

By now, you know everything about this when we are working with a normal function. but wait :)
there is more to learn.
Things go to change a little when we talk about arrow functions.

First, we should know that an arrow function could not be called as a constructor function(with `new` operator).
The second point is that we can never change this for an arrow function. even by creating a new one with the help of `bind`.
And the third, last, and most important point is that the value of this for an arrow function is not determined by How we call it but is determined by **Where we declare it first**.
there are two important words above,
The first is **Where**
by "where", I mean in which function scope(opposed to object or block scope) we are creating that arrow function. let's see an example.

![arrow function this](https://dev-to-uploads.s3.amazonaws.com/i/9lp52dmg2owt4vlojng4.png)
when logMyThis method was being declared, the main function of the app was running with this value of window or global. so when javascript interpreter looks at this (arrow) function expression, it behaves like below:

![how arrow function this is bound](https://dev-to-uploads.s3.amazonaws.com/i/ydi4a85wjahnv4yu72p5.png)
It creates a new function bound to the `this` in the main function(that is global object).
Let's talk about a more complex example:

![arrow function this complex example](https://dev-to-uploads.s3.amazonaws.com/i/obeafij4o79brdxb9gby.png)
It's all about where(and when) an arrow function is declared.last but not least, is the second word: **first**
take a look at the example below

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/qsfd8klbplq6a43ofuu9.png)
As you can see there is no difference How we call the function. when this is bound for the first time, it will remain bound, forever :)

---

If you found this post useful and enjoyed reading it, please leave a comment below. it's my first post and I am looking forward to getting feedback as much as possible.
Also if you think that there is something wrong with this post, please let me know.

Thanks for reading