# Digging into "this" context in JavaScript

# JavaScript and `this`

I've had some confusions when studying debounce and throttle functions. In particular, I was confused about how `this` worked in those functions.

# The confusion

Let's go over some code:

```js
const dog = {
  name: "Rex",

  // When you write a method like this:
  bark() {
    console.log(`${this.name} says woof!`);
  },

  // JavaScript stores it roughly like this:
  // bark: function() {
  //     console.log(`${this.name} says woof!`);
  // }
};
```

We have an object `dog` with a method `bark`.

When you call `dog.bark()`, `this` will point to `dog`. So [`this.name`](http://this.name) will be `"Rex"`.

What happens if you do this?

```js
const justBark = dog.bark;
justBark();
```

This is where my confusion started. You would imagine `this` would point to `dog` again, but it doesn't.

# How JavaScript functions work

Why is that?

If you look at the comments of the code above, JavaScript essentially stores the method `bark` as a function like this:

```js
bark: function() {
    console.log(`${this.name} says woof!`);
}
```

One of the flexible things about JavaScript is that you decide what `this` points to. To me this was really confusing but that's how the language works.

Bark under the hood is just a function:

```js
function bark() {
  console.log(`${this.name} says woof!`);
}
```

When you call `justBark()`, `this` points to the global object. In a browser, `this` points to `window`. If that doesn't have a `name` property, it'll be `undefined`.

# JavaScript method call under the hood

Under the hood, a simplified version of how a method call works. Mind you, JavaScript internals are likely very different, but this is a simplified version:

```js
// Let's recreate what JavaScript does when you call methods
// This is a simplified version of JavaScript's internal method lookup
function callMethod(obj: any, methodName: string) {
  // Step 1: Look up the function on the object
  const func = obj[methodName];
  console.log("Step 1: Found function:", func);

  // Step 2: When called with dot notation (obj.method()),
  // JavaScript automatically binds 'this' to the object
  console.log("Step 2: Calling function with 'this' set to:", obj);
  func.call(obj); // This is what happens behind the scenes
}
```

# Final example

```js
const dog1 = {
  name: "Rex",
  bark() {
    console.log(`${this.name} says woof!`);
  },
};

const dog2 = {
  name: "Barkley",
};

// This will log "Barkley says woof!"
dog1.bark.call(dog2);
```

A final example to demonstrate how `this` works. Methods in reality are just functions decoupled from objects. If you call `dog1.bark()`, JavaScript will internally do something like `callMethod(dog1, "bark")`.

And if you do [`dog1.bark.call`](http://dog1.bark.call)`(dog2)`, JavaScript will internally do something like `callMethod(dog2, "bark")`.

In this case, a cleaner example would be:

```js
function bark() {
  console.log(`${this.name} says woof!`);
}

bark.call(dog2);
```

Now, we can reuse `bark` for different objects in a "clean" way. But, it's important to emphasize that it doesn't matter whether you explicitly define it as a standalone function or it'sa method of an object. Under the hood, it's just a function referring to the `this` context.
