`This` Keyword JavaScript -Simplified!!
Tags: webdev, javascript, beginners, node
Published: 2023-10-31 06:12:48

**`this`** keyword is a special variable that is created for every execution context (every function) Takes the value of points to the owner of the function in which the `this` keyword is used.

*Note: `this` keyword is not Static, means it depends on how the method/function is called and its value is only assigned when the function is actually called*

```js
const jonas = {
name: 'Jonas',
year: 1990,
calcAge : function(){
return 2023 - this.year
}
}
jonas.calcAge(); //33
```

Notice here what is the value of the `this` keyword here? it is the object `jonas` therefore `this.year` can actually access the `year` property, since it is same as saying `jonas.year`


![Description image of object and this](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0jgqru80kzeskjuazcpp.png)



A better example to understand this
```js
const person = {
  firstName: 'John',
  lastName: 'Doe',
  getFullName (){
    return this.firstName + ' ' + this.lastName;
  }
};

console.log(person.getFullName()); // Outputs 'John Doe'

const person2 = {firstName:'Sam', lastName:'Smith'}
person2.getFullName = person.getFullName;
console.log(person2.getFullName()) //Outputs 'sam Smith'
//so here the getFullName actually copied from person but this is based on the way how it is actually called, so here it is called on person2 therefore it takes firstName and lastName of the person2 i.e, Sam Smith
```

### `this` keyword in the strict mode

In case of the strict mode, if we make a simple function call, the `this` keyword returns `undefined` value. Where as if we are not in the strict mode, the `this` keyword will returns the window object in the browser.

for example in case of 
1.`normal mode`
```js
function sayHello() {
  console.log(this); // Refers to the global object (window in a browser)
}

sayHello(); // Calling the function

// In a browser:
// Output: Window { ... }
```
2.`use strict` mode
```js
"use strict";

function sayHello() {
  console.log(this); // Refers to undefined
}

sayHello(); // Calling the function

// Output: undefined
```
the value of `this` in a function call depends on the context in which the function is called. In strict mode, when a function is called without a specific context, `this` is `undefined`. Using strict mode can help catch potential issues and make the behavior of `this` more predictable in your code.
### `this` keyword in Arrow functions
The arrow functions does not get their own this keyword, so in case of the methods in objects defined as with arrow functions, the this keyword will point to the nearest otherwise to the global window object. So in case of the arrow function the `this` keyword is known as **lexical `this`**

for example:
```js
var firstName = 'John(Global)' //notice var declartion in global gets the window object
const person = {
  firstName: 'John',
  lastName: 'Doe',
  getFullName: () => {
    return this.firstName + ' ' + this.lastName;
  }
};

console.log(person.getFullName()); // Outputs 'John(Global) undefined'
```

### `this` keyword in case of event listener
in this case the `this` keyword will point to the DOM element that the handler is attached to

let us explore one example here
```js
<button id="myButton">Click Me</button>
<script>
  const button = document.getElementById('myButton');

  function handleClick() {
    console.log(this); // Refers to the button element
  }

  button.addEventListener('click', handleClick);
</script>
```

When you use a regular function as an event handler, the value of `this` inside the function refers to the DOM element that triggered the event. In this example, when the button is clicked, the `handleClick` function is called as an event handler, and within that function, `this` refers to the button element that triggered the click event.

**notice what happens when we use the arrow function as event listeners**

```js
<button id="myButton">Click Me</button>
<script>
  const button = document.getElementById('myButton');

  const handleClick = () => {
    console.log(this); // Refers to the global object (e.g., window)
  };

  button.addEventListener('click', handleClick);
</script>

```
In this example, even though the `handleClick` arrow function is attached as an event handler to the button element, `this` inside the function refers to the global object (e.g., `window` in a browser environment). Arrow functions do not have their own `this` context and capture it from their surrounding lexical context.


### Control the value if `this` with `.call` and `.bind`

explicitly control the value of `this` within an event listener, you can use techniques like `.bind()`, `.call()`, or `.apply()`. Here's an example using `.bind()`:

example:
```js
<button id="myButton">Click Me</button>
<script>
  const button = document.getElementById('myButton');

  function handleClick() {
    console.log(this); // Refers to a custom object
  }

  const customObject = { name: 'Custom Object' };

  button.addEventListener('click', handleClick.bind(customObject));
</script>
```
n this case, we use `.bind()` to bind the `handleClick` function to the `customObject`, so within the event handler, `this` refers to `customObject`

![Explanatory of this](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1rbn60cirtwgmfy3umd.png)



### Some more use-cases of `this` with call and bind methods.


In JavaScript, both the `.call()` and `.bind()` methods are used to manipulate the `this` context of a function. They allow you to control the value of `this` when invoking a function, which can be especially useful in various programming scenarios. However, they differ in how they handle the `this` context and their application.

**.call() Method:**

The `.call()` method is used to invoke a function with a specified `this` context and a list of arguments. It immediately executes the function, allowing you to explicitly set the value of `this` for that function call. You can also pass arguments one by one after the `this` context.

Example:

```javascript
const person = {
  fullName: function() {
    return this.firstName + ' ' + this.lastName;
  }
};

const person1 = {
  firstName: 'John',
  lastName: 'Doe'
};

const person2 = {
  firstName: 'Jane',
  lastName: 'Doe'
};

// Using .call() to invoke the fullName function with a specified this context
console.log(person.fullName.call(person1)); // Output: John Doe
console.log(person.fullName.call(person2)); // Output: Jane Doe
```

**.bind() Method:**

The `.bind()` method is used to create a new function with a specified `this` context, without immediately invoking the function. It allows you to create a new function that, when called, has its `this` value set to the provided value. This can be especially useful for creating function wrappers or for event handling.

Example:

```javascript
const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

const unboundGetX = module.getX;
const boundGetX = unboundGetX.bind(module);

console.log(boundGetX()); // Output: 42
```

**Use Cases:**

- **.call():** It is commonly used when borrowing methods from other objects, or when you need to set the `this` value explicitly for a function call.
- **.bind():** It is often used in event handlers, or when you want to create a function with a specific context that can be called later, such as when creating a callback function with a predetermined `this` value.

Understanding how and when to use `.call()` and `.bind()` can help you control the `this` context effectively and ensure that your functions behave as intended in different programming contexts.