How "this" Works
Tags: javascript, beginners, tutorial
Published: 2023-01-04 14:42:05

## About "**this**"

The `this` keyword in JavaScript could be considered one of its more difficult concepts to grasp. To better understand `this`, we first need to know what `this` is. The simple definition of `this` is that `this` refers to the object that is executing the current function. We should also note that JavaScript is an object-oriented language. It's important to know this because in JavaScript, `this` is used to refer to the current object or to the current event. While this may seem easy to understand, `this` can be more difficult in practice. The value of `this` may vary depending on how the function containing`this` is called and executed. This has to do with the execution context of the function. For example if we where to write 

```javascript
function whatsThis(){
    console.log(this)
}

whatsThis(); // => window obj.
```

As we can see `this` in this context is referring to the window obj. It may seem like the value of `this` should be the function itself, but remember that the value of `this` is the object which is executing the function never the function itself. In this case the object that is executing the function is the global object. The reason is when the function is being declared inside the global scope, it is not nested inside of a "parent" obj so it refers to the global obj which is the window. The purpose of this blog will be to explain how `this` changes depending on when and where it is used.

## Working With 'this'

We seen above how `this` used in a stand alone function binds to the window object, but how can we get `this` to work for us. One way would be to call a function as a method of an object. for example 

```javascript
const player = {
name: 'Jack',
func: function(){
   console.log(`Hello ${this.name} do you want to play a game?`);
 }
}

player.func() // => 'Hello Jack do you want to play a game?'
```

In this example, `this` is **bound** to the player Object, essentially `this === player`. This is called Implicit binding, we will talk about **binding** `this` in the next section. For now, let's think about why `this` is the player and not the window. before, when we tried to use `this`, we used `this` in a stand alone function. The stand alone function was declared in the global context. Now we defined the function as a method of player. puting the function (func) inside the context of player so the object calling the function now is not the window but the player object. but we still need to be careful. Take a look at this example. 

```javascript
const person = {
  name: 'Sam',
  sayName: function() {
    console.log(`My name is ${this.name}`);
  }
};

const sayName = obj.sayName;

sayName(); // outputs "My name is undefined", because "this" is the window object

```
This may be confusing because sayName is defined as a method of the person object, but we are getting undefined. Well, this is happening because when we call sayName as a standalone function the value of this becomes the window again. That is do to the fact that the function is no longer being called as a method of the person object. At this point, it might not seem like `this` has a purpose. Why would we need `this` if it can only be used inside the object? What is the point? To answer those questions we need to talk about binding.

## Binding `this`

There are several ways to use `this`, and there are different ways to bind this. above we already discussed two types of binding "implicit binding", and "Window binding" but there are Two other types of binding. Let's take a deeper look at each of them.

### Implicit Binding

Implicit binding is when a function is called as a method of an object, `this` is bound to the object that the function is a method of. like in the example above. 

### Explicit Binding

Explicit binding is when we use the methods 'call', 'apply', and 'bind', and we explicitly bind `this` to a object. for example:

``` javascript
const greet = function(greeting) {
  console.log(`${greeting}, my name is ${this.name}`);
}

const person1 = { name: 'John' };
const person2 = { name: 'Jane' };

greet.call(person1, 'Hello'); // Output: "Hello, my name is John"
greet.apply(person2, ['Hello']); // Output: "Hello, my name is Jane"

const boundGreet = greet.bind(person1);
boundGreet('Hello'); // Output: "Hello, my name is John"

```
In the example above, we see that when we use these methods we can change what this is bound to. This brings us out of only being able to use `this` in side of the object we define the function in. we can now bind a function to any object and the return value of `this` will become the object it is bound to, like in the example.

### New Binding

New binding is when a function is called using the `new` keyword, `this` is bound to the newly  created object. for example: 

```javascript
function Person(name) {
  this.name = name;
}

const person = new Person('John');
console.log(person.name); // Output: "John"
```
This is called a constructor function. when we use a constructor function each `new` obj will have this bound to the person object created by the function above.

With the knowledge of the different ways to bind `this` to an object, or even how to create an object using `this`. We can now see that the `this` keyword has multiple uses, and can be used to both simplify and expand our code in useful ways.

## Arrow Functions With `this`

When it comes to arrow functions they use `this` a bit differently. Because arrow functions do not define its own `this` context they inherit the context of the parent function. Now that may sound similar to what we discussed previously, but its not. What this means is that if we use an arrow function it will look for the next **function** with context not **object**. Before when we declare the function as a method the function tells this to bind to the object executing the function. With arrow functions this does not happen. here is an example of how an arrow function would handle being declared as a method on its own. 

```javascript
const person = {
  name: 'Tim',
  sayName: () => {
    console.log(this.name);
  }
};

obj.sayName(); // outputs 'undefined', because "this" is the window object
```
Before when we did this with a anonymous function, the function told `this` to bind to the object executing it, person. Now with an arrow function the function is not telling `this` to bind to the object so this looks for the next function with context and that is the window. and since window has no name property it returns undefined. Next let's look at an example of how we can get `this` to work with an arrow function like the one above.

```javascript
const person = {
  name: 'Tim',
  sayName: function() {
    const innerFunc = () => {
      console.log(this.name);
    };
    innerFunc();
  }
};

person.sayName(); // => 'Tim'
```
In this example we get the response we are looking for. The reason is because the arrow function looks for the next function with context, in this case it is the anonymous function the arrow function is nested in. Then,  this takes on the value of the object calling the anonymous function like we have seen before.
 

## Conclusion

Yes `this` can be a very complicated topic to grasp. Once we are able to understand `this` we not only gain access to a extremely beneficial tool, we also gain a better understanding of how javascript operates. We gain a better understanding of context and object oriented programing. Not only simplify solutions but come up with new and unique ways to accomplish task.