How exactly ‘this’ Keyword Works in JavaScript

zmjdev
3 min readJan 20, 2021

You are expected to have a good understanding of functions and objects in JavaScript and basic knowledge of dynamic scoping and lexical scoping.

Chances are you have already been frustrated by the “this” keyword in your JavaScript career. The worst part is that sometimes it behaves exactly how you expect it to behave and only a few times, it doesn’t. This makes you believe your idea of this “this” keyword is mostly correct. And that’s the reason you may still be unaware of how it exactly works.

Rather than developing a wrong idea, understanding how exactly it works will save you from all the frustrations you encounter.

You may have heard JavaScript is a dynamically scoped language. But, it is not a dynamically scoped language.sometimes, it is. Well, let me explain what I mean.

JavaScript is a lexically scoped language. It is the “this” keyword that makes you think that JavaScript is dynamically scoped. That is why the“this” keyword in JavaScript is so powerful. Unfortunately, most JavaScript developers don’t have a good understanding of the “this” keyword which makes them hate it. Let me show you what I mean.

In the above code snippet, we defined only one function. Look at that, we got different outputs according to different call sites. This is why the “this” keyword is more powerful. You may wonder how it all happened. The reason is that the value of “this” is assigned based on how the function is invoked.

There are only four ways to invoke a function in JavaScript:

1. sayHello()2. worker1.sayHello() — an object on the left side of the “.” calling its method3. sayHello.call(worker3) —using call4. new sayHello()— using the new keyword

Let’s see how exactly the value of the “this” keyword gets assigned.

1. sayHello()

When you invoke a function like this, the “this” keyword will point to the global object. In this case, the window object. And in the window object, there is no property labelled name. That is, window.name is undefined. That’s how we got undefined.

2. worker1.sayHello()

I told you some time you get the expected output. This is the scenario I described. When you invoke a function like this, “this” refers to the object on the left side of the “ . ” (dot) — it is the same as all other languages. In this case, the worker object calls the method. Now, this.name becomes worker.name. That is how we got the above output.

3. sayHello.call(worker3)

When you invoke a function with _.call(), The _.call() will assign the first argument you provide to “this”. In this case, this=worker. Now, this.name becomes worker.name, ie, “zmjdev”.

4. new sayHello()

When you invoke a function with “new” keyword, the “new” returns a object and “this” will point to that object. In this case,the returned object is empty as we didn’t prefix any variable inside sayHello() with “this”. That is {}.name is undefined.

If you want to learn more about the “new” keyword, refer to the following article.

Note — The “this” keyword acts entirely different in arrow functions. We will see that in another article.

More content at plainenglish.io

--

--