Javascript Object #9
Tags: javascript, webdev, web3, programming
Published: 2023-04-13 06:53:10

We have seen so many important things about Javascript Object.But now we are going to see another most important topic,which is _this_ in Javascript.

## this 
 As you may came across many programming languages and have a good familiarity about the **this** keyword.But in Javascript **this** keyword in totally different.Let's know about the Strange this keyword in Javasciript.

```
`In Javascript **this** is the Object of which Function is property.In more simple words,**this** reference to the Object of that is currently calling the Function.`
```
let's see this with an example,

```
`let counter = {
  count: 0,
  next: function () {
    return ++this.count;
  },
};

counter.next();`
```

as you can see,here counter is an Object and next() is a method inside the counter Object,as you can see inside the Object. The this keyword inside the method references the current Object **counter**.

But this is not enough,we have to check the **this** keyword on differenct context like,

1. **Global Context**.
2. **Function Context**.

## Global Context.

```
`console.log(this === window); // true`
```

In Global context,**this** refers the Global Object,in Browser it is the Window Object and in NodeJs Environment it is Global Object.And this behaviour is same in both _Strict_ and _non strict_ mode.
And If you assign a property with **this** in Global context,Javascript will add the Property to the window Object,as like this,

```
`this.color= 'Red';
console.log(window.color); // 'Red'`
```

## Function Context.
In Javascript you can call the Function in Following ways,

1.Function Invocation.
2.Method Invocation.
3.Constructor Invocation.
4.indirect Invocation.

## Function invocation.

Inside the Function the _this_ keyword differs in Strict and Non Strict mode.let's see

```
`function show() {
   console.log(this === window); // true
}

show();`
```
When you call the show() function, the this references the global object, which is the window on the web browser and global on Node.js.

```
`Calling the show() function is the same as:
window.show();
`
```

But in the Strict mode,Javascript sets the **this** inside the Function context as **undefined**.Let's see that with an example,

```
`"use strict";

function show() {
    console.log(this === undefined);
}

show();`
```

If you want to enable the Strict mode use the directive **"use strict"** in the beggining of the Javascript file,or else you can use the Strict mode inside the specific function.

```
`function show() {
    "use strict";
    console.log(this === undefined); // true

    function display() {
        console.log(this === undefined); // true
    }
    display();
}

show();`

Output:
true
true
```

As you can see the strict mode applies for both the function and Nested function as well.

## Method invocation
When you call a method of an Object, Javascript set the **this** to the Object that contains that method.Let's see this with a quick example,

```
`let car = {
    brand: 'Honda',
    getBrand: function () {
        return this.brand;
    }
}

console.log(car.getBrand()); // Honda`
```
In this example, the this object in the getBrand() method references the car object.

Let's Go little tricky here,as getBrand is a Property of a Object and it can be Stored in variable right.Yes, Let's do it.

```
`let brand = car.getBrand;
console.log(brand()); // undefined
`
```
ufff, Strange right.for me too this things looks so strange untill i know the exact reason.when you assign the brand variable with the Object getBrand property,this will assign the Property but what happens is, the brand variable is now in global context and it reference the Global Object,thus inoder to fix this we have to bind the brand variable to the exact Object.

```
`let brand = car.getBrand.bind(car);
console.log(brand()); // Honda
`
```

To fix this issue, you use the bind() method of the Function.prototype object. The bind() method creates a new function whose the this keyword is set to a specified value.

Let's see another example,

```
`let car = {
    brand: 'Honda',
    getBrand: function () {
        return this.brand;
    }
}

let bike = {
    brand: 'Harley Davidson'
}

let brand = car.getBrand.bind(bike);
console.log(brand());

Output:

Harley Davidson`
```

In this example, the bind() method sets the this to the bike object, therefore, you see the value of the brand property of the bike object on the console.

## Constructor invocation 
When you use the new keyword to create an instance of a function object, you use the function as a constructor.

```
`function Car(brand) {
    this.brand = brand;
}

Car.prototype.getBrand = function () {
    return this.brand;
}

let car = new Car('Honda');
console.log(car.getBrand());`
```

The expression new Car('Honda') is a constructor invocation of the Car function.JavaScript creates a new object and sets this to the newly created object. This pattern works great with only one potential problem.
Now, you can invoke the Car() as a function or as a constructor. If you omit the new keyword as follows:

```
`var bmw = Car('BMW');
console.log(bmw.brand);
// => TypeError: Cannot read property 'brand' of undefined`
```

Since the this value in the Car() sets to the global object, the bmw.brand returns undefined.

ES6 introduced a meta-property named new.target that allows you to detect whether a function is invoked as a simple invocation or as a constructor.

You can modify the Car() function that uses the new.target metaproperty as follows:

```
`function Car(brand) {
    if (!new.target) {
        throw Error('Must use the new operator to call the function');
    }
    this.brand = brand;
}`
```

## Indirect Invocation

In JavaScript, functions are first-class citizens. In other words, functions are objects, which are instances of the Function type.

The Function type has two methods: call() and apply() . These methods allow you to set the this value when calling a function. For example:

```
`function getBrand(prefix) {
    console.log(prefix + this.brand);
}

let honda = {
    brand: 'Honda'
};
let audi = {
    brand: 'Audi'
};

getBrand.call(honda, "It's a ");
getBrand.call(audi, "It's an ");`
```

Code language: PHP (php)

In this example, we called the getBrand() function indirectly using the call() method of the getBrand function. We passed honda and  audi object as the first argument of the call() method, therefore, we got the corresponding brand in each call.

The apply() method is similar to the call() method except that its second argument is an array of arguments.

```
`getBrand.apply(honda, ["It's a "]); // "It's a Honda"
getBrand.apply(audi, ["It's an "]); // "It's a Audi"`
```

Thanks for You Mean Time,
Sam