# Understanding the 'this' Keyword in JavaScript

### **What exactly is 'this'?**

In JavaScript, `this` is a keyword that refers to the object it belongs to. The specific object it references depends entirely on how the current function is being called. Its behavior is dynamic, meaning its value changes depending on the context in which it's used.

### **Common Scenarios for 'this'**

**1\. Global Context**

In the global execution context (outside of any function), `this` refers to the global object. In a browser, the global object is `window`, so `this` in a global context would refer to `window`.

```javascript
console.log(this)
//output: Window {0: global, window: Window, self: Window, document: document, name: '', location: Location, …}
```

**2\. In a Regular Function**

In a regurlar function call, `this` refers to the global object (in non-strict mode) or `undefined` (in strict mode).

**'strict' mode**

In 'strict' mode, `this` inside regular functions that are not part of an object will be `undefined`, preventing accidental reference to the global object.

```javascript
function whatsThis() {
    console.log(this); 
}

whatsThis(); //output: Window {0: global, window: Window, self: Window, document: document, name: '', location: Location, …}
```

**3\. In an Object Method**

When used inside a method belonging to an object, `this` refers to the object itself.

```javascript
const person = {
  name: "Alice",
  greet: function() {
    console.log("Hello, " + this.name);
  }
};

person.greet(); // Output: "Hello, Alice"
```

`Understanding Function Borrowing`

When a function is assigned to a variable or another object, `this` will refer to the object it is called with, not where it was originally defined.

```javascript
const person = {
  name: "Bob",
  greet: function() {
    console.log("Hello, " + this.name);
  }
};

const greetFunc = person.greet;
const person2 = { name: "Charlie", greet: greetFunc };

person2.greet(); // Logs "Hello, Charlie"
```

In the above example, when `greet` is called as a method of `person2`, `this` within the `greet` function now refers to `person2`, because `greet` is being called with `person2` as the context. Therefore, `this.name` is "Charlie", and the function logs "Hello, Charlie" to the console.

The crucial point in this example is understanding that the value of `this` inside a function depends on the object it is called upon, not where the function was defined or assigned. When `greetFunc` is called as part of `person2`, `this` refers to `person2`, resulting in "Hello, Charlie" being logged.

**3\. In a Constructor Function**

When a function is used as a constructor (with the `new` keyword), `this` refers to the newly created object.

```javascript
function Person(name) {
  this.name = name;
}

const person = new Person('John');
console.log(person.name); //Output: "John"
```

**4\. In a Event Listener**

In event listeners, `this` usually refers to the HTML element that triggered the event.

```javascript
const button = document.querySelector("button");
button.addEventListener("click", function() {
    console.log(this); // Output: the button element
});
```

### **Arrow Functions and 'this'**

We know that `this` within a function depends on how the function is called. Traditional functions (declared with the function keyword) have their `this` value set dynamically at the time they are invoked. This means that the same function can have different `this` values depending on its calling context.

However, **arrow functions**, behave differently. They do not have their own `this` binding. Instead, they "inherit" the `this` value from the lexical scope in which they were defined. This means the value of `this` inside an arrow function is the same as the value of `this` in the outer function or global scope (if not defined inside a function) where the arrow function was created.

**Example 1 -&gt;**

```javascript
const obj = {
  show: () => {
    console.log(this);
  }
};

obj.show(); // In a browser, 'this' will log 'window' because it's captured from the global scope
```

**Example 2 -&gt;**

```javascript
const person = {
  name: 'Alex',
  activities: ['run', 'jump', 'throw'],
  showActivities: function() {
    this.activities.forEach((activity) => {
      // Arrow function inherits 'this' from showActivities method context
      console.log(`${this.name} likes to ${activity}`);
    });
  }
};

person.showActivities();

// Output:
// Alex likes to run
// Alex likes to jump
// Alex likes to throw
```

In this example, the arrow function passed to `forEach` inherits the `this` value from the `showActivities` method's context. Therefore, `this.name` inside the arrow function correctly refers to `person.name`

### Conclusion

Since `this` is so context-dependent, it's sometimes a source of confusion. Always be mindful of the context in which your functions are being called to understand the value of `this`. Using `console.log(this)` is a great debugging tool.
