`this` Just In: Discover the Hidden Powers of `this` in Javascript - The Beginners Guide To Javascript(Part 12)
Tags: javascript, beginners, programming, tutorial
Published: 2023-05-12 20:33:18

Hello, code lovers! Today, we're going to dive deep into the magical, sometimes maddening, yet absolutely essential world of the "this" keyword in JavaScript. If you've ever been left scratching your head by "this" (pun intended), you're in the right place. We're here to clear up the mystery, one code snippet at a time. Buckle up and let's get started!

## What is "this"?

In JavaScript, "this" is a special keyword that refers to an object - the one that's currently being worked with. It's like JavaScript's version of a magic mirror, reflecting back the object in question. It can be anything from the global window object in a browser to a specific object you've created, depending on where and how you're using it.

```javascript
const myObject = {
  property: 'I am a property!',
  method: function() {
    console.log(this.property);
  }
};

myObject.method();  // Outputs: 'I am a property!'
```

In the example above, "this" refers to `myObject`. It's like the method is saying, "Within my current home (`myObject`), what is the `property`?"

## Why does "this" exist?

So, why do we need "this" in JavaScript? It's all about context. JavaScript is an object-oriented language, which means we often interact with objects. "this" lets us access properties and methods within the object's context. It gives us a convenient way to refer to the object we're working on, without having to know its name.

Imagine you're a famous author signing autographs (nice, huh?). Instead of having to ask each fan's name, you could just refer to the current one as "this fan". In JavaScript world, that's what "this" is doing for us.

## Automatic binding of "this" within functions

Now, how is the value of "this" set? Most often, it's bound automatically by JavaScript.

When you call a function as a method on an object, "this" gets automatically set to the object you're calling the method on. It's like JavaScript's way of saying, "Hey, you're working with this object now!"

```javascript
const myObject = {
  greet: 'Hello',
  greetFunc: function() {
    console.log(this.greet);
  }
};

myObject.greetFunc(); // Outputs: 'Hello'
```

In this example, "this" inside `greetFunc` automatically refers to `myObject`

## The binding of "this" within arrow functions (ES2015)

Arrow functions, introduced in ES2015, have a unique feature: they do not bind their own "this". Instead, they inherit "this" from the parent scope. It's like a child inheriting their parent's eye color - it just happens!

```javascript
const myObject = {
  greet: 'Hello',
  greetFunc: () => {
    console.log(this.greet);
  }
};

myObject.greetFunc(); // Outputs: undefined
```

In this case, "this" does not refer to `myObject`, but the global object (like `window` in a browser), because that's the parent scope of the arrow function.

## Explicitly determining the binding of "this"

But what if we want to control what "this" refers to? JavaScript has us covered with `call`, `apply`, and `bind`.

```javascript
const myObject = {
  greet: 'Hello'
};

function greetFunc() {
  console.log(this.greet);
}

greetFunc.call(myObject);  // Outputs: 'Hello'
```

In this example, we used `call` to make "this" inside `greetFunc` refer to `myObject`. `apply` works the same way, but with a slightly different syntax, and `bind` creates a new function with "this" bound to the specified object.

## Bonus Material

Now, let's look at a common pitfall with "this" - nested functions:

```javascript
const myObject = {
  greet: 'Hello',
  greetFunc: function() {
    function innerFunc() {
      console.log(this.greet);
    }
    innerFunc();
  }
};

myObject.greetFunc(); // Outputs: undefined
```

In this case, "this" inside `innerFunc` does not refer to `myObject`, but the global object. This is because `innerFunc` is not a method on `myObject`, but a standalone function inside `greetFunc`.

To solve this, we can use an arrow function (which doesn't bind "this") or bind "this" to the function:

```javascript
// Using an arrow function
const myObject1 = {
  greet: 'Hello',
  greetFunc: function() {
    const innerFunc = () => {
      console.log(this.greet);
    }
    innerFunc();
  }
};

myObject1.greetFunc(); // Outputs: 'Hello'

// Using Function.prototype.bind
const myObject2 = {
  greet: 'Hello',
  greetFunc: function() {
    const innerFunc = function() {
      console.log(this.greet);
    }
    innerFunc.bind(this)();
  }
};

myObject2.greetFunc(); // Outputs: 'Hello'
```

And there you have it! You've just taken a whirlwind tour of "this" in JavaScript. Remember, "this" is like a mirror - it reflects the object you're working on, so you can access its properties and methods. It's a powerful tool, but with great power comes great responsibility. Use it wisely, and your JavaScript code will thank you!