Understanding the"this” Keyword in JavaScript
Tags: javascript, node, react
Published: 2020-09-10 15:32:20

The `this` keyword is a fundamental concept in JavaScript, and also an incredibly confusing one to both new developers and those who have experience in other programming languages. In JavaScript, `this` is a reference to an `object`. The object that this refers to can vary, `implicitly` based on whether it is global, on an object, or in a constructor, and can also vary `explicitly` based on usage of the Function prototype methods bind, call, and apply.

#### Here we will cover

* `this` in Global Environment
* `this` inside Functions
* `this` in Methods
* `this` With the Call and Apply Methods
* `this` With the Bind Method
* `this` With the Fat-Arrow Function

**1) `this` in Global Environment**

By default, the execution context for any execution is global, which means if we are running any simple function, then `this` refers to a [global object](https://developer.mozilla.org/en-US/docs/Glossary/Global_object).

*"As we know `window` is the global object in the case of the `browser`, However, if we are using  `NodeJS`, then a special object `global` is the global object."*

`On Browser`
```JAVASCRIPT
function foo () {
        console.log("Simple function call");
	console.log(this === window); 
}

foo();	//prints true on console
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sraanqhb9d1fmkb9v2v3.PNG)

When a function is invoked with the `new keyword`, then the function is known as a constructor function and returns a new instance. In such cases, the value of this refers to a newly created instance.

```JAVASCRIPT
function foo () {
	console.log("Simple function call");
	console.log(this === window); 
}

const result = new foo(); //prints false on console

```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/9ha0038wdowu0wjefvzx.PNG)


`Using Node`

```
> this === global
true
```
**2) `this` inside Functions**

```JAVASCRIPT
function Hero(heroName, realName) {
  this.realName = realName;
  this.heroName = heroName;
}
const superman= Hero("Superman", "Clark Kent");
console.log(superman);
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/o9tnfmoy11unbwhxin1g.PNG)

Note that this function is not written in strict mode. Running this code in the **node** will not get us the value of `Superman` and `Clark Kent` as we expected, but it will instead just give us an **undefined**.

The reason behind this is that since the function is not written in `strict mode`*, this refers to the global object.

If we run this code in `strict mode`, we will get an error because JavaScript does not allow us to assign properties `realName` and `"heroName` to undefined. This is a good thing because it prevents us from creating global variables.

Lastly, writing the function’s name in uppercase means that we need to call it as a constructor using the new operator. Replace the last two lines of the above code snippet with this:

```JAVASCRIPT
function Hero(heroName, realName) {
  this.realName = realName;
  this.heroName = heroName;
}
const superman= new Hero("Superman", "Clark Kent");
console.log(superman);
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wj40o5cufy17hxshwrmn.PNG)

**3) `this` in Methods**
```JAVASCRIPT
const hero = {
  heroName: "Batman",
  dialogue() {
    console.log(`I am ${this.heroName}!`);
  }
};
hero.dialogue();
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3w7xg1qrkjxrpsq852dq.PNG)
**4) `this` With the Call and Apply Methods**

call and apply are very similar-they invoke a function with a specified this context and optional arguments.

The only `difference between call and apply` is that call requires the arguments to be passed in one-by-one, and apply takes the arguments as an array.

```JAVASCRIPT
const book = {
  title: 'Brave New World',
  author: 'Aldous Huxley',
}

function summary() {
  console.log(`${this.title} was written by ${this.author}.`)
}

summary()
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wvmzpkvtv8emiby2yjta.PNG)

Since summary and book have no connection, invoking summary by itself will only print `undefined`, as its looking for those properties on the global object.

```JAVASCRIPT
const book = {
  title: 'Brave New World',
  author: 'Aldous Huxley',
}
let title = 'abc';
let author = 'test';
function summary() {
  console.log(`${this.title} was written by ${this.author}.`)
}
summary.call(book);
// or:
summary.apply(book);

summary();
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/7kgmi3wtcqce669gj0ou.PNG)

**5) `this` With the Bind Method**
The bind method returns a new method with this referring to the first argument passed. We’re going to use the above example to explain the bind method.
```JAVASCRIPT
function Person(fn, ln) {
	this.first_name = fn;
	this.last_name = ln;

	this.displayName = function() {
		console.log(`Name: ${this.first_name} ${this.last_name}`);
	}
}

let person = new Person("John", "Reed");
person.displayName(); // Prints Name: John Reed
let person2 = new Person("Paul", "Adams");
person2.displayName(); // Prints Name: Paul Adams

let person2Display = person.displayName.bind(person2);  // Creates new function with value of “this” equals to person2 object
person2Display(); // Prints Name: Paul Adams
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/lckk1cvccpqn5nqwzajp.PNG)

**6) `this` With the Fat-Arrow Function**
unlike Regular functions, the arrow function does not have their own `this` keyword. ```The value of this inside an arrow function remains the same throughout the lifecycle of the function and is always bound to the value of this in the closest non-arrow parent function.```
{% gist https://gist.github.com/vandnakapoor19/1105c8c9855e906f8da52894bc25d55f %}
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/f93aha2je1ybp8nxzcx3.PNG)