Skip to main content

Javascript 102 : Understanding 'this' keyword

The keyword "this" is frequently misunderstood when coding with Javascript. It is because its behavior depends on the execution context.

Now what is "execution context"?

It is mainly of three types. Global Execution Cotnext (GEC), Functional Execution Cotnext (FEC) and Eval.

In GEC, it is the global environment which Javascript  (JS) is running. If you are running the script in a browser and you use the "this" keyword, it will refer to the "Window" object. But if you are using NodeJS and running the script outside a browser the "this" keyword would refer to the "Process".

In FEC the "this" keyword would refer to the execution context created by the code inside the function.

EVAL is hen you use the "this" keyword inside an "eval" function.

If this does not make sense, don't worry because we are going to understand with an example which is always the best way.

Make the following HTML files in your code editor and and open in a browser. I use chrome and its developer tools.  (The complete code is given at the end of this post)


You should see the following result in the developer tools console. animalTypeOuter() function is called in the global context. So when the console.log() calls the "this.animalType", "this" keyword refers to the "animalType" global variable which holds the value "dog".

And also notice that, "this", and "window" object both are same, because line 15 and 16 both prints "Window" object in console. This again proves the point that in this example "this" refers to the global "Window" object.


If you expand the "Window" output in the console you should see, that it includes both "animalType" variable, as well as "printAnimalOuter" function.



Now change the code as follows.

An "animal" object is created with a property "animalType" (This is private to the object and it is not as same as the "animalType" variable in the global context).

Another property called "printAnimalInner" is created and it is assigned with "printAnimalOuter" function. "printAnimalOuter" function a global function so this object has access to it, hence this assignment is legal. Now the property "printAnimalInner" is actually a method and it is same as "printAnimalOuter" function.

Now what do you think the output will be on the line 20?


The output as follows, and if you are confused please think through it a little bit before reading any further.

On line 20, you called the function "printAnimalInner" of the "animal" object, and it is as same as calling "printAnimalOuter" function. So why the difference?


When you call "printAnimalInner" function, what you actually call is "printAnimalOuter" function but within the "animal" object. Now the "printAnimalOuter" tries to print "this.animalType". But since the function is called inside the "animal" object, the execution context here is not global. It is functional. The function looks for an "animalType" variable and it actually finds one with the value "Cat" assigned to it. so it prints that.

That is the explanation for the above output.

Now change the code as follows. and observe the output. Can you figure out why?  

Output:

It is because on line 24, the "printAnimalInner" function would again look for a variable "animalType" and it finds the one with the value "dog" attached to it.

As you can see, the value of the "this" keyword depends on the "execution context".

Now, check out the following code. Only change is on line 25.  

The function "call()" is a special method and and you can pass the "execution context" as an argument to it.

So passed the "animal" as the execution context and bound it to the anonymousFunction().

Now the "this" keyword operates in the execution context of "animal" and in there the value of "animalType" variable is "Cat", hence it gives the following output.


Following is another way to do the same thing.




Now, look at the following code and try to figure out the output by your own.


Output:


I recommend you type everything by your own, but if you are too lazy you can copy the following code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <script>

        var animalType = 'dog' ; // This is a global variable
        printAnimalTypeOuter('Whisky') ;

        function printAnimalTypeOuter(name){
          console.log(this.animalType + ', ' + name);
        }

        var animal = {
          animalType: 'Cat',
          printAnimalTypeInner: function(){
            return function(name){
              console.log(this.animalType + ', ' + name + ' in the Cat object');
            }
          }
        };

        var anonymousFunction = animal.printAnimalTypeInner().bind(animal) ;
        anonymousFunction('Kitty') ;

    </script>

    <title>Understanding "this" keyword</title>
</head>
<body>

</body>
</html>




Comments

Popular posts from this blog

Javascript 101 : var, let and const

Let's understand variable types "var", "let" and "const" in Javascript.  Basically there are 3 ways to create variables in java script using 3 keywords as follows.  There differences are as follows,  01. The "variable01" which was created with "var" keyword, does not have a blocked scope. which means, you have to be careful when using it. A variable declared inside an "if" block can be changed outside the block.  02. The "variable02" which was created with "let" keyword, has blocked scope. A variable with "let" keyword declared inside an "if" block is not available outside the block. 03. The "variable03" which was created with "const" keyword, is a constant. Which means you have to initialize it once you declare it, and that value cannot be modified later in the programs. There will be an error if you try to do so.  Now lets explore