Loading Now
×

JavaScript Advanced: The ‘this’ Keyword

JavaScript Advanced: The ‘this’ Keyword

One of the trickiest and most confusing topics or keywords in JavaScript is ‘this’. It requires a deep understanding. However, in the beginning, you might have to use ‘this’ in your code with a fifty-fifty chance of getting it right. After practising several times and learning the rules, you will gradually understand the ‘this’ keyword completely. ‘this’ is a reserved keyword in JavaScript, meaning you cannot use this name for any variables or functions. It is used in many different ways and contexts. So, it’s not expected that you will understand ‘this’ in all situations from the beginning. But if you know the basic rules of how ‘this’ works, it won’t take long to understand even bigger and more complex code. The value of ‘this’ is determined based on how the function is called. Its value is set at the time of execution. Confusing? Yes, let’s start from scratch. Here, we will try to understand it in our own way. Just remember the following five rules that will help determine the value of ‘this’:

1. Global Context Rules

2. Object Rules

3. Explicit Rules

4. New Keyword Rules

The rules I mentioned here are not official, but they are quite helpful in understanding the ‘this’ keyword, which is why I wrote them this way.

### 1. Global Context Rules:

In the global execution context, outside of any functions, ‘this’ always refers to the global object. In a browser, that global object is the window object. In Node.js, it is the global object. In the global context, the value of ‘this’ remains the same in both strict mode and non-strict mode.

Let’s say we directly log ‘this’ to our browser’s console:

“`javascript

console.log(this);

“`

You’ll see it shows the window object:

“`javascript

console.log(this);

Window {postMessage: f, blur: f, focus: f, close: f, frames: Window, …}

“`

To see it more clearly, you can also check this:

“`javascript

console.log(this == window);

“`

This will show true:

“`javascript

console.log(this == window);

true

“`

This means they are the same. The value of ‘this’ in the global context remains the same in both strict mode and non-strict mode.

Now, if we use ‘this’ inside a defined function, its value will depend on how you call the function. Here, the value might differ in strict mode and non-strict mode.

For example:

“`javascript

function helloThis() {

    console.log(this);

}

helloThis();

“`

In this example, ‘this’ shows the global object (window object in the browser). This is because, even though ‘this’ is used inside the function, due to the global execution context, it still refers to the global object.

The same thing won’t work in strict mode:

“`javascript

function helloThis() {

    ‘use strict’;

    console.log(this);

}

helloThis();

“`

Here, you’ll see the result is undefined:

“`javascript

function helloThis() {

    ‘use strict’;

    console.log(this);

}

helloThis();

undefined

“`

The reason it works in one mode but not in the other is that we used ‘use strict’. Strict mode was introduced to avoid bad practices. In JavaScript, many things fall outside the rules. By using ‘this’ inside a function, we might accidentally create a global variable, which isn’t possible in strict mode. Therefore, in non-strict mode, ‘this’ refers to the global object, but in strict mode, it shows undefined.

This idea brings us to constructor functions and the new keyword, which will be discussed in our fourth rule. So, details will be discussed in the next topic.

Accidental global variables sometimes work like this:

“`javascript

function unNamed() {

    this.name = ‘Zonayed Ahmed’;

}

unNamed();

“`

If you call a variable named ‘name’ outside this function, you’ll see it works:

“`javascript

console.log(name);

> Zonayed Ahmed

“`

Why? Because when you wrote ‘this.name’ inside the function and called that function in the global context, ‘this.name’ actually got assigned under the global object (window.name). Therefore, you can access it from anywhere outside. This won’t work in strict mode.

Now, if we use ‘this’ inside a custom-defined object, what will happen? Our second rule will come into play.

### 2. Object Rules:

If you define a custom object and use ‘this’ keyword inside its method, its value won’t refer to the global object. Here, its value will change:

“`javascript

var myCustomObj = {

    name: ‘Zonayed Ahmed’,

    age: 21,

    job: ‘Student’,

    msg: function() {

        console.log(this);

    }

};

myCustomObj.msg();

“`

In this example, the method inside the custom object refers to the closest custom-defined object itself, according to the object method rules:

“`javascript

myCustomObj.msg();

> {name: “Zonayed Ahmed”, age: 21, job: “Student”, msg: f}

“`

If there is another object inside this object and you use ‘this’ in a function inside that nested object, what will happen? Let’s see an example:

“`javascript

var myCustomObj = {

    name: ‘Zonayed Ahmed’,

    age: 21,

    job: ‘Student’,

    anotherObj: {

        name: ‘Ahmed Zonayed’,

        msg: function() {

            console.log(‘My name is: ‘ + this.name);

        }

    }

};

myCustomObj.anotherObj.msg();

“`

Here, ‘this’ will refer to the nearest object, which is ‘anotherObj’, so ‘this.name’ will refer to ‘anotherObj.name’:

“`javascript

myCustomObj.anotherObj.msg();

> My name is: Ahmed Zonayed

“`

To make it clearer:

“`javascript

var myCustomObj = {

    name: ‘Zonayed Ahmed’,

    age: 21,

    job: ‘Student’,

    anotherObj: {

        name: ‘Ahmed Zonayed’,

        value: function() {

            console.log(this);

        }

    }

};

myCustomObj.anotherObj.value();

“`

Here, calling the ‘value’ function in the second object will show:

“`javascript

myCustomObj.anotherObj.value();

> {name: “Ahmed Zonayed”, value: f}

“`

However, we mentioned earlier that the value of ‘this’ depends on how the function is called. What does that mean? Let’s see an example:

“`javascript

var myCustomObj = {

    name: ‘Zonayed Ahmed’,

    age: 21,

    job: ‘Student’,

    msg: function() {

        console.log(this);

    }

};

myCustomObj.msg();

“`

If we directly call ‘msg()’ inside the object, it will refer to ‘myCustomObj’:

“`javascript

myCustomObj.msg();

> {name: “Zonayed Ahmed”, age: 21, job: “Student”, msg: f}

“`

### 3. Explicit Rules:

You might have heard of the call, bind, and apply methods. These are used to explicitly determine the value of ‘this’. If you see these methods used somewhere, you can easily understand what ‘this’ refers to because these methods set the reference of ‘this’ through their first parameter. Let’s use one in our previous example:

“`javascript

var myCustomObj = {

    name: ‘Zonayed Ahmed’,

    age: 21,

    job: ‘Student’,

    anotherObj: {

        name: ‘Ahmed Zonayed’,

        value: function() {

            console.log(this);

        }

    }

};

myCustomObj.anotherObj.value();

“`

Here, ‘this’ refers to ‘anotherObj’:

“`javascript

myCustomObj.anotherObj.value();

> {name: “Ahmed Zonayed”, value: f}

“`

But if we explicitly set ‘this’ to refer to ‘myCustomObj’ instead of ‘anotherObj’ using the call method:

“`javascript

var myCustomObj = {

    name: ‘Zonayed Ahmed’,

    age: 21,

    job: ‘Student’,

    anotherObj: {

        name: ‘Ahmed Zonayed’,

        value: function() {

            console.log(this);

        }

    }

};

myCustomObj.anotherObj.value.call(myCustomObj);

“`

Now, ‘this’ refers to ‘myCustomObj’:

“`javascript

myCustomObj.anotherObj.value.call(myCustomObj);

> {name: “Zonayed Ahmed”, age: 21, job: “Student”, anotherObj: {…}}

“`

The call, bind, and apply methods can only be used with functions to determine the execution context, as we did in the example. They cannot be used with other data types like objects, strings, numbers, or booleans. Moreover, we used call here instead of bind or apply, and the reasons for that will be discussed later.

### 4. New Keyword Rules:

Lastly, the new keyword is another widely used keyword that can determine the value of ‘this’. If ‘this’ is somehow within the scope of the new keyword, its value might be different. This will be discussed in detail later, as we need to clarify some more concepts first.

Post Comment