The `this` Keyword in JavaScript
Tags: this, javascript, keyword, object
Published: 2020-10-23 12:09:04

In this article, we will remove the confusion of the `this` keyword in JavaScript.

First, we need to understand the difference between a `function` and a `method`.


A `function` is a block of code to perform a particular task and it **Stands Alone**.

example:

```javascript
function sayHello() {
   console.log("Hello")
}
sayHello(); // Hello
```

A `method` is also a `function` but it is **inside** an `object`

example:

```javascript
const person = {
  name: "John",
  sayHello: function(){
    console.log("Hello");
  }
}

person.sayHello() // Hello
```
So, if `this` is inside a `method`, `this` will refer to the **Object** itself.

example:

```javascript
const person = {
  name: "John",
  sayHello: function(){
    console.log(this);
  }
}

person.sayHello();
/*{
name:"John",
sayHello:f sayHello {...}
}*/
```
And, if `this` is inside a `function`, `this` will refer to the **Global** Object which is the `window` Object in Browsers and the `global` Object in Node.

example:

```javascript
function sayHello(){
  console.log(this);

sayHello(); //:[object Window]
```

##The Constructor Function.

We use a `constructor function` to create a **blueprint** of an **Object**.
And because of this, the `this` keyword will refer to the created object.

_the `new` keyword creates a new empty object { }_

example:

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

const p1 = new Person("John");
const p2 = new Person("Doe");
p1.log(); 
/* Person {
name:"John",
log: {...}
}*/
p2.log();
/*Person {
name:"Doe",
log: {...}
}*/

```

## The Confusion Starts Here.

Consider this code and try to guess what the `this` will refer to.

```javascript
const person = {
  fName: "John",
  skills: ["HTML", "CSS", "JS"],
  logSkills: function(){
    this.skills.forEach(function(skill){
      console.log(`${this.fName} can do ${skill}.`)
    })
  }
}

person.logSkills();

```
>Is your answer => 
_John can do HTML
John can do CSS
John can do JS_?

Unfortunately, your answer is wrong.
>the correct answer is => 
_undefined can do HTML
undefined can do CSS
undefined can do JS_

since `this.fName` will be `undefined`.
because `this` will refer to the **window** object, and window.fName is `undefined`.

But why you may wonder? isn't **function(skill){ }** is inside the person object?

Well, this not quite right.
The `this` is inside a callback function.
And a callback function is just a regular function.

So, `this` will definitely refer to the **window** object.

That's why we tend to use  [Arrow Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) as callback functions Since it Does not have its own bindings to `this`.


Now when we substitute a regular callback function to an Arrow Function you will get the result you expected.

```javascript
const person = {
  fName: "John",
  skills: ["HTML", "CSS", "JS"],
  logSkills: function(){
    this.skills.forEach((skill)=>{
      console.log(`'${this.fName}' can do '${skill}'.`)
    })
  }
}
person.logSkills();
/*
John can do HTML.
John can do CSS.
John can do JS.
*/
```

<a href="https://www.linkedin.com/in/youssefzidan/" target="_blank">
    <img src="https://img.shields.io/badge/LinkedIn-%230077B5.svg?&style=flat-square&logo=linkedin&logoColor=white" alt="LinkedIn">