Understanding JavaScript the weird parts: `this` context
Tags: javascript, webdev, node
Published: 2020-03-22 11:22:17


<br> 

![](https://cdn-images-1.medium.com/max/1600/1*sVczE2UnKFzRT9HNxN32MA.jpeg)


The `this` keyword in JavaScript has confused a lot of developers. Whether you are just starting your career in programming or you are an experienced
developer. It confuses everyone alike.

*****

Now before starting let’s get into the fundamentals of how `this` works in
javaScript. `this` always refers to the calling context of a function inside an object, which will usually be the object with which the function is associated with. Now, Since we have so many libraries at our disposal in the javascript ecosystem we just grab a library and start building something without actually understanding what is going on. While you will be able to build amazing applications but when it comes to debugging those applications that’s when the understanding of the weird parts of the javaScript comes into the picture. Now, javaScript is still evolving even after so many years but the fundamentals of language will always remain the same.

*****

> `this` does not refer to the function in which it is used, but always refers
> to the object in which it is executed. Let’s understand this by an example.

    const obj={
      myFunction: function(){
      console.log(this===window)
     }
    }

    obj.myFunction()


![](https://cdn-images-1.medium.com/max/1600/1*4yCjsswZ1o65KzchKQP55A.png)


Now, in the above example, we expect this behavior because here `this` will always refer to the calling context of a function which here is obj.


![](https://cdn-images-1.medium.com/max/1600/1*7ThhYAOlX7H4k7xJdEG23Q.png)


Now this behavior will be true in any other object-oriented language. This is the default assumption because this is how `this` works in most other languages. Now, let’s change a few things and see how the behavior of `this` changes.


![](https://cdn-images-1.medium.com/max/1600/1*_fckZJjwgLPz6IqUxpQ7OA.png)


Now, in this example object declaration is the same but here we assign it
another variable and the call it afterward instead of calling it right away. Now if we call the newVariable, suddenly the value of `this` changes from `obj` to the `global` or `window`.  Now, this tends to trip up a lot of developers. Now in order to understand what value `this` will hold we need to look where it is being called not where it is written. In the above example, it is being called in the global object and not the `obj` object.

*****

Let's look at some complex examples.

    const obj={
      myFunction: function(){
      console.log(this===obj)
      setTimeout(function(){
        console.log(this===obj)
        console.log(this===window)
      })
     }
    }

    obj.myFunction()


Now, this example is similar to the above example but here we use setTimeout which is an asynchronous task. Now, if we run this we get something different.


![](https://cdn-images-1.medium.com/max/1600/1*gvfrmdd52NipDvpiNL_72g.png)


We see that inside setTimeout now the value of this again changes back to the `window` or `global` depending upon the environment i.e Nodejs or browser. Now even though it’s the same block of code the value of `this` changes to `window`. Now, going back to the first rule `this` does not depend on where the function is being written but where it is called and in case of asynchronous calls a new `async function` object on the `window` object. Okay, now let’s take a look at the same example but written a little differently using an ES6 arrow function.

    const obj={
      myFunction: function(){
      console.log(this===obj)
      setTimeout(()=>{
        console.log(this===obj)
        console.log(this===window)
      })
     }
    }

    obj.myFunction()



![](https://cdn-images-1.medium.com/max/1600/1*5O688u-4SUSQ0Ok2vqwX1g.png)


Interestingly, Now the value of `this` changes back to `obj` instead of `window`. An important thing to note is that `this` always get binding happens in 3 ways- default binding, implicit binding, and explicit binding. Now whenever we define a standalone function execution, it is always a default binding and it always binds to `window` object.

![](https://cdn-images-1.medium.com/max/800/1*kjsw9C2n8qoHv-Ud6Mlf5w.png)


Now, we have to keep that default binding will always be our fallback binding.

*****

Let’s get to know a little bit about Explicit and Implicit binding and
understand how that works.

**Implicit Binding**

Now implicit binding happens whenever we have a function call and whatever is to the left side of the dot it is going to refer to that.

![](https://cdn-images-1.medium.com/max/800/1*69lYQt4J_fWuNbONslrxEw.png)


In this example, we have obj to the left side of the dot so it is going to refer to that i.e `obj`.   

<br> 

**Explicit Binding**

Explicit binding of `this` occurs when [.call()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call),[.apply()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply), or [.bind()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind) are used on a function.

We call these explicit because you are explicitly passing in a `this` context to call() or apply(). Let’s take a look at how explicit binding looks like in the following example.

    const obj={
      myFunction: function(){
      console.log(this===obj)
     }
    }

    const newFunctionVariable=obj.myFunction

    newFunctionVariable.apply(obj)


![](https://cdn-images-1.medium.com/max/800/1*lBJMSv-zcJoDap9o2GyJ2g.png)



Now even though we are assigning `myFunction` to a new variable we can still say to what `this` context this function call will be bound to. We can see this by looking at another example where we can bind it to a completely different object below.


    const obj1={

    firstName:"Sachin",

    lastName:"Thakur",

    myName:function(){

    console.log(this.firstName+" "+this.lastName)

    }

    }

    const obj={

    myFunction: function(){

    console.log(this)

    console.log(this==obj1)

    }

    }

    const newFunctionVariable=obj.myFunction

    newFunctionVariable.apply(obj1)


![](https://cdn-images-1.medium.com/max/800/1*pmVXwuH_Ms9HfGk2HoAZ1w.png)


Now, in this, if we pass the first parameter as `obj1`it will take the `this` reference of `obj1` even though the function is defined on `obj`. And this is how the Explicit binding works.

*****

Now with the introduction of ES5 arrow function, the javaScript engine
introduced a new behavior. Before arrow functions, every new function defined its own `this` value based on how the function was called:

* A new object in the case of a direct function call with `window` context as `this` (Default Binding)
* `undefined` in [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode) function calls.
* The base object if the function was called as an “object method”.(Implicit Binding)
* You could also Explicitly define what `this` will refer to like we saw in the last example. (Explicit Binding)

An arrow function does not have it’s own `this`. The `this` value comes from the lexical scope. Arrow function follows the normal variable look rule. If the value is not found in its scope go one level up and find the value in the enclosing scope. That’s why we don’t need to bind `this` value to the object explicitly as long as it is available in it’s enclosing scope.

Thus, in the following code, the `this` within the function that is passed to `setTimeout` has the same value as the `this` in the lexically enclosing
function:

<br> 

    const obj={
      myFunction: function(){
      console.log(this===obj)
      setTimeout(()=>{
        console.log(this===obj)
      },0)
     }
    }
    obj.myFunction()


![](https://cdn-images-1.medium.com/max/800/1*2ASnZWCWtu2TQpExeTMrYw.png)

**Conclusion**

`this` can be a little tricky sometimes but if we know the basic fundamentals of how scoping words and how javaScript treats an object, we can easily understand how these core concepts work. `this` can be a little tricky in case of callback or async function where the value of `this` changes. Always remember `this` value is assigned the value of the object where it is being invoked.