Javascript this 101
Tags: javascript, this, programming, webdev
Published: 2019-11-13 19:12:14

---
title: Javascript this 101
published: true
description: What's this? 
tags: javascript, this, programming, webdev
canonical_url: https://irian.to/blogs/javascript-this-101
---

`this` is one of the most common JS keywords. You see them everywhere, but it can be hard to tell what `this` is.

I will cover 3 scenarios where `this` may be used: globally, inside a regular function, and inside arrow function. This should cover most usage. 

1. Global `this`
2. `this` inside a regular function
3. `this` inside arrow function

Let's start by looking at some examples! 

Btw, I will be doing this inside browser (chrome) console, not node module. I will also assume strict mode is not used.

# Global `this`

If we just type `this` in our browser console, it will refer to window/ global object.

```
this // Window {...}

var helloVar = 'helloVar'
this.helloVar // helloVar

window.helloWindow = 'helloWindow'
this.helloWindow // 'helloWindow'

const helloConst = 'helloConst'
this.helloConst // undefined

let helloLet = 'helloLet'
this.helloLet // undefined
```

You see that `let` and `const` can't be called through `this`. They are not stored inside "object environment record", but inside "declarative environment records". Explaining this will be outside of this article's scope. Here's a [link](https://www.ecma-international.org/ecma-262/6.0/#sec-declarative-environment-records) if you're interested.


# `this` inside a regular function

Let's start by an example:

```
const obj = {
    breakfast: 'donut',
    wutBreakfast: function() {console.log(`I had ${this.breakfast} this morning!`)}
}
window.breakfast = 'waffles';

obj.wutBreakfast() // I had donut this morning!
```
Here we observe that `this` inside `this.breakfast` refers to the object itself. Look at where the function call is when calling `obj.wutBreakfast()`. Ask yourself: "Is there an object to the left of my function call?" That object is where your `this` refers to.

What if there is no object to the left of function call? If you are calling a function without an object to the left of function call, you can assume it is the global object. In this case, the `Window` object. 
Let's look at the next example:

```
function sayBrunch(){
    console.log(`I had ${this.brunch} for brunch!`)
}

sayBrunch() // I had undefined for brunch
```
We haven't defined anything for brunch yet, so it returns undefined. Let's define it inside window object

```
window.brunch = 'oatmeal'
function sayBrunch(){
    console.log(`I had ${this.brunch} for brunch!`)
}

sayBrunch() // I had oatmeal for brunch!
```


Let's do few more examples to build your intuition:

```
window.dinner = 'pizza'
const foodObj = {
  dinner: 'spaghetti',
  sayDinner: function(){
        console.log(`I had ${this.dinner} for dinner!`)

  }
}
foodObj.sayDinner() // what does it return?
```

Another one, with a little twist. We defined a window appetizer string and a mealObj.appetizer string. We call sayAppetizers from two different objects. What do you think each will return? 

```
window.appetizer = 'chocolate';

function sayAppetizer(){
    console.log(`I had ${this.appetizer} for appetizer!`)
}
const mealObj = {
  appetizer: 'ice cream',
  sayAppetizer: sayAppetizer
}
mealObj.sayAppetizer() // what does it return?
sayAppetizer() // what does it return?
```

Just remember, `this` inside regular JS function refers to the object immediately to the left  where the function is called. If there is no object, assume it is a window object.

With this in mind, even if we have `obj1.obj2.obj3.someFunc()`, we know that `this` inside `someFunc()` will refer to `obj3` because it is the closest object to where function is called.


# `this` inside arrow function

This behaves differently inside an arrow function. There are **three** things you need to keep in mind the whole time:

1. **Only** regular function and global function can have `this`.
2. Arrow function does **not** have `this` on its own
3. When `this` is referred to inside an arrow function, it will look up the scope to find this value. It behaves like lexical scope.

Let's look at first example:

```
let myObj = {
  breakfast: 'taco',
  sayBreakfast: () => {
    console.log(`I had ${this.breakfast} for breakfast`)
  }
}
window.breakfast = 'pizza'

myObj.sayBreakfast() // pizza
```

Let's see if this makes sense while keeping the 3 rules above in mind:
when we call myObj.sayBreakfast(), it looks up to myObj, but since myObj does **not** have `this` (rule #2), it will look one more up, the global/ window object (rule #1). It saw that global/window has `this.breakfast = 'pizza'`, so it prints pizza. 

Now add a regular function to object:

```
let myObj = {
  breakfast: 'taco',
  sayBreakfast: () => {
    console.log(`I had ${this.breakfast} for breakfast`)
  },
  sayRegBreakfast: function() {
    console.log(`I had ${this.breakfast} and it was yummy`)
  }
}
window.breakfast = 'pizza'

myObj.sayBreakfast() // pizza
myObj.sayRegBreakfast() // taco
```
You'll see that using regular function gives "taco" and arrow gives "pizza".

Let's call an arrow function from global object scope. We should expect it to have `this` from global scope. Is it true?

```
window.secondBreakfast = 'eggs';

const saySecondBreakfast = () => {
  console.log(`I had ${this.secondBreakfast} for second breakfast!`)
}

saySecondBreakfast() // eggs
```

I was in disbelief when I see this either, so let's prove it further. The example below is from [getify archive](https://web.archive.org/web/20160625172303/http://blog.getify.com/arrow-this/):

```
function foo() {
    return function() {
        return function() {
            return function() {
                console.log("Id: ", this.id);
            }
        }
    }
}
foo.call( { id: 42} )()()() // undefined
```
vs

```
function foo2() {
   return () => {
      return () => {
         return () => {
            console.log("id:", this.id);
         };
      };
   };
}
foo2.call( { id: 42 } )()()() // 42
```

(Btw, [call](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) assigns `this` to function we are calling - foo/ foo2 itself - with the argument object we pass)

Remember that only arrow function looks up lexically; the first example looks for `this` inside the *third* nested function and found nothing, so it returns undefined. 

While foo2, finding no `this` inside third nested function, lexically looks up for next available reg/ global function's `this`. It found foo2's `this` (from `foo2.call({id: 42})`) first (remember rule #1), so it prints 42.

If there had been a regular function on the second example earlier, it wouldn't have found it, like:

```
function foo3() {
   return () => {
      return function() { // this is regular function now
         return () => {
            console.log("id:", this.id);
         };
      };
   };
}
foo3.call({id:101})()()() // undefined
```

But if we gave `this` to where the `return function() {...})` is, it would have found it. Because when arrow function lexically looks up and found the first regular function, that function is given `this` value of 101. 

```
function foo3() {
   return () => {
      return function() { 
         return () => {
            console.log("id:", this.id);
         };
      };
   };
}
foo3()().call({id: 101})() // 101
```


So that's it folks! This is definitely only the tip of iceberg, but `this` should be enough to get you started - pun intended 😁.

Let me know if you have questions/ found mistakes - thanks for reading and happy codin'!!

# More Readings:
- [YDKJS](https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/objects-classes/README.md
)
- [Let me explain to you what is this javascript](https://dev.to/ycmjason/let-me-explain-to-you-what-is-this-javascript-44ja)
- [What is this](https://dev.to/basedenergy/what-is-this-4onl)
- [Javascript this keyword (youtube)](https://www.youtube.com/watch?v=gvicrj31JOM)
- [Arrow function and this](https://stackoverflow.com/questions/28798330/arrow-functions-and-this)