UNDERSTANDING THE "THIS" KEYWORD IN JAVASCRIPT
Tags: javascript
Published: 2019-10-02 21:27:47

For someone who starts learning JavaScript as their first coding language, understanding the this keyword is one of the big challenges to be encountered. It took me quite a while to fully assimilate the different use cases of this JavaScript concept. It is one of those core aspects such as scope, closures and hoisting that need a lot of drilling and practice until they sink in for good.

After reading documentation from different sources and following a few tutorials online, I got to understand when and how to use it. Although practice is what made it stick in. 

And now let's get into the meat. The this keyword behaves somehow as an object pointer. It points at different things based on how it is called. Unless otherwise specified, this will always point to its parent object. By default, this parent object is the window object, which contains the DOM document. Window is the global object in the browser. However, it is important to note here, that if we run the same function in the terminal using Node.js, i.e the backend JavaScript run-time environment, the default value of this is global object since we are no longer in the browser.

In the following lines I will divide this core javascript concept in four different use cases.

##**Case 1: When used in combination with `bind`, `apply`, and `call`**

When used with the javascript native methods bind, apply or call, the value of this is set explicitly, and it always behaves the same, giving us full control over what we assign as this. That being said, there are several differences between these three methods. And I will explain them in the lines that follow. But what the three of them have in common is that they change the value of this to something else.

__Used with bind__

`bind` is a method on functions by default, and so are `apply` and `call`. `bind` returns a copy of the function it's called on, where `this` is set to the first argument passed into `bind`.

In the next section we will tackle `apply` and `call`, but for now let’s test how `this` works with `bind`. First of all, let’s write a simple function that prints out the default value of `this`. Go to your favourite browser open the [developer tools](https://developers.google.com/web/tools/chrome-devtools/open), and open the console to write the function:

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

We are now going to use this function with bind in order to change the default value of this into something of our choice. We will declare a variable, and we will assign to this variable the returned function that results from binding this to the object that we pass as an argument of bind. You can now call the new function. What do you get as an output? What is the new value of this?

```javascript
var explicitlySetTheValueOfThis = whatIsThis.bind({name: 'Barcelona'});
explicitlySetTheValueOfThis();
```

### **bind vs apply and call:**

`apply` and `call` change the value of `this` inside the function, just like `bind` does. The big difference though, is that they also run the new function immediately. As we saw, `bind` just returns a copy of the function, and then you have to run the new function as a second step.

Something important to note here is that a function returned from `bind` cannot be bound to a different `this` value ever again.

### **apply vs call:**

If the function where we use `apply` and `call` has no arguments other than the first one -where we pass in the new value of `this`, then both methods will behave alike. However, if the function where we use `apply` and `call` has arguments, `apply` and `call` will behave differently.

And here is the difference: when you pass arguments into a function with `apply` you need to pass them in an array. So the second argument of `apply` is an array whose items are the arguments that we were going to pass into the original function.

Contrarily to `apply`, with `call` we don't use an array, we just pass the arguments into the function one after the other, following the first argument, where we had passed in the new value of `this` that we wanted to bind with `call`.

As a result, if we copy and paste the following code into the console, the output will be the same in both cases. The only thing that changes is the way we provide the function with the arguments that it needs.

```javascript
function logThisWithGreeting(greeting, name) {
	console.log(greeting, name);
	console.log(this);
}
logThisWithGreeting.apply({name: 'Alex'}, ['hi', 'Alex']);
logThisWithGreeting.call({name: 'Alex'}, 'hi', 'Alex');
```

## **Case 2: When `this` appears in object methods.**

When a function is called as a method - a function inside an object, `this` points to that parent object. Let's write some code that represents this scenario. In the same console you previously opened, write now an object which contains a method. All this method should do, like the function we saw in case 1, is to log the value of `this`. Then call that object method. What output do you get? You should get the object that, when calling the method, was on the left side of the dot. You will not see the name of the object, but you should get an object that contains the method that you just called.

```javascript
var strangeObject = { 
	myMethod: function(){
		console.log(this);
	}
};
strangeObject.myMethod();
```

## **Case 3: When `this`  is used in constructor functions.**

When a function is called as a constructor, `this` points to the object that the constructor is creating. In case you don't have a clear idea of what a constructor function does, here is a [video](https://www.youtube.com/watch?v=23AOrSN-wmI) that might enlighten you. But in short, a constructor is a function that returns an object. Factory functions return objects too, but constructor functions are called with the `new` keyword and they are capitalised. [Here](https://medium.com/javascript-scene/javascript-factory-functions-vs-constructor-functions-vs-classes-2f22ceddf33e) is a very good article by Eric Elliot that helped me better understand the difference between constructor and factory functions.

Let's now test `this` in constructor functions. Open your console, and write a constructor function to create objects with one property, the city name. The function will have one parameter, which will take a string argument, the name of a city. Now, you can assign to a variable called `myCity` the value returned from running the constructor function with the `new` keyword. Don't forget to pass in your city as the argument. Here's an example. What output did you get? console.log the variable to see it.

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

var myCity = new City('Barcelona');
console.log(myCity);
```

## **Case 4: `This` and regular functions vs arrow functions**

When we explained `bind`, `apply` and `call` in the first use case, we wrote the following function to log the value of `this`:

```javascript
// this used in regular functions
function whatIsThis() {
	console.log(this)
}
```

Regular functions, like the one above, and like the object methods that we saw in case 2, have their own `this` keyword, which points to the parent object in scope. If the scope of our function at the time it executes is the global object, `this` will refer to the global object, as specified in the introduction to this article.

However, what if we use an arrow function instead? Arrow functions are tricky because they don't always behave like a regular function, even if we can use them for the same purposes in most cases. One of the things they differ from each other is the `this` keyword. Simply, arrow functions don't have their own `this` keyword. This means we can still use `this` inside an arrow function, but its value will not be the parent object of the function. The value of `this` in an arrow function is that one of `this` as used outside the scope of the function. 

If we write the example above as an arrow function, the result will be the same, not because `this` points to the parent object of the function, but because `this` is the `window object`. It would be as if we ran `console.log(this)` in the global scope.

However, and here we will see different results, what if we use arrow functions as an object method?

```javascript
// global scope

// regular function used as method
var myObjectRegular = { 
	regularMethod: function() {
		console.log(this)
	}, 
}; 

myObjectRegular();
// Expected result:
// {regularMethod: ƒ}

// arrow function used as method
var myObjectArrow = { 
	arrowMethod:() => console.log(this), 
}; 

myObjectArrow();
// Expected result:
// Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}
```
If we run the code above, for the regular method, the value of `this` is the parent object of the function. But when running the arrow method, the value of `this` is the window object. This proves that arrow functions don't have `this` and that when we use `this` inside of an arrow function, it points to the value of `this` as used outside the function.

As a final note, I would like recap an important detail that I mentioned a few lines ago but didn't give much focus. That is, the `this` keyword gets its value assigned when the function is being executed, not when it's being declared.

Let’s have a look at an example where we grab a DOM element and attach an event listener to it. Where is `this` going to refer to? 

 Open the developer tools of your browser, edit the DOM and insert a very simple button with an id attribute:

```html
<button id="myButton">What is this</button>
```

Then go to the console tab and write the following code, which basically logs to the console the value of this when clicked:

```javascript
var myObject = {
	logValueOfThis: function() {
		console.log(`value of this: ${this}`);
	}
}

document.getElementById('myButton').addEventListener('click', myObject.logValueOfThis);
```
Now if we close the developer tools and click on the button, I don't see `valueOfThis: {logValueOfThis: f}`  as the value of `this` but  `value of this: [object HTMLButtonElement]`.

This means the value of `this` at the time of execution of the callback function was the `button` object. Whenever we set up an event listener, the event handler function will  execute as if it were attached to the element object.

So what will we do to have `this` pointing to `myObject`? We will need to rebind our method to `myObject` by calling `bind`.

```javascript
document.getElementById('myButton').addEventListener('click', myObject.logValueOfThis.bind(myObject));
```
## **WRAPPING UP**

In this article, I tried to introduce in a simple and yet detailed way one of the pillar concepts of JavaScript. I aimed to engage you by testing the cases that I was presenting. And I have provided some support with links to resources in case you need to extend on some of the topics that are mentioned here. Together with the `this` keyword, concepts such as higher order functions, callback functions, functional programming, constructor functions and factory functions are key to any individual who aims to become a professional JavaScript developer. 

On a personal note, I started in programming three years ago, following the decision of a major career change. I am a former translator and language teacher and I had never done any programming before whatsoever. It has not been an easy trip and there are many frustrations that came along the way. But thanks to this experience, I have learnt what things are particularly difficult to understand for someone coming into programming following a non-academic path. If that is your case, and you are taking your first steps, this article was specially written with the aim to help you, even if only in an introductory way.