# The Magic of this, call(), apply(), and bind() in JavaScript

## Introduction

If you've spent any time with JavaScript, you've probably run into `this` and walked away confused. It behaves differently depending on where it shows up. And `call()`, `apply()`, and `bind()` sound similar enough that most people lump them together without really understanding what each one does differently.

This post clears all of that up. No execution context internals, no spec language. Just what you need to know to write better code.

* * *

## What `this` Actually Means

The simplest way to think about `this`: it refers to whoever called the function.

Not where the function was defined. Not where it lives in your code. Who called it.

That one shift in thinking makes most of the confusion go away.

* * *

## `this` Inside a Regular Function

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

greet();
```

When you call a plain function like this, `this` points to the global object. In a browser, that's `window`. In Node.js, it's `global`. In strict mode, it's `undefined`.

Nobody specific called it, so JavaScript falls back to the global object by default.

* * *

## `this` Inside an Object

Things get more useful when functions live inside objects.

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

person.greet(); // Hi, I'm Alice
```

Here, `person` is the one calling `greet`. So `this` is `person`, and `this.name` is `"Alice"`.

Now watch what happens when you pull the function out of the object:

```javascript
const greet = person.greet;
greet(); // Hi, I'm undefined
```

The function is the same. But now nobody owns the call. `this` falls back to the global object, and `name` isn't defined there, so you get `undefined`.

This is the source of most `this` bugs.

* * *

## `call()`: Borrow a Function, Choose Your `this`

`call()` lets you run a function and tell it exactly what `this` should be.

```javascript
const person1 = { name: "Alice" };
const person2 = { name: "Bob" };

function greet(city) {
    console.log(this.name + " lives in " + city);
}

greet.call(person1, "New York"); // Alice lives in New York
greet.call(person2, "London");   // Bob lives in London
```

The first argument to `call()` sets `this`. Everything after that gets passed as individual arguments to the function.

Think of it as: "Run this function, but pretend it belongs to this object."

* * *

## `apply()`: Same Idea, Arguments as an Array

`apply()` works exactly like `call()`. The only difference is how you pass arguments. Instead of listing them one by one, you pass an array.

```javascript
function greet(city, country) {
    console.log(this.name + " is from " + city + ", " + country);
}

const person = { name: "Alice" };

greet.apply(person, ["Paris", "France"]); // Alice is from Paris, France
```

Both lines below do the same thing:

```javascript
greet.call(person, "Paris", "France");
greet.apply(person, ["Paris", "France"]);
```

`apply()` is handy when your arguments are already stored in an array.

* * *

## `bind()`: Create a Fixed Version of a Function

`call()` and `apply()` run the function immediately. `bind()` is different. It returns a new function with `this` permanently locked in, but doesn't call it yet.

```javascript
const person = { name: "Alice" };

function greet() {
    console.log("Hi, I'm " + this.name);
}

const greetAlice = greet.bind(person);

greetAlice(); // Hi, I'm Alice
greetAlice(); // Hi, I'm Alice (always Alice, no matter what)
```

You can store that bound function and call it later. It will always use the `this` you gave it.

This is especially useful for event handlers and callbacks, where you lose control of what `this` will be.

```javascript
const button = {
    label: "Submit",
    handleClick: function () {
        console.log("Clicked: " + this.label);
    }
};

const handler = button.handleClick.bind(button);

// Later, passed as a callback
setTimeout(handler, 1000); // Clicked: Submit
```

Without `bind()`, `this` inside `setTimeout` would not be `button`.

* * *

## Comparison: `call` vs `apply` vs `bind`

|  | `call()` | `apply()` | `bind()` |
| --- | --- | --- | --- |
| Runs the function? | Yes, immediately | Yes, immediately | No, returns a new function |
| How you pass args | One by one | As an array | One by one (at bind time or call time) |
| Fixes `this`? | For that call only | For that call only | Permanently |
| Returns | Function result | Function result | New function |

* * *

## When to Use Each One

Use `call()` when you want to run a function once with a specific `this` and you have the arguments ready individually.

Use `apply()` when you have the same situation but your arguments are already in an array.

Use `bind()` when you need to pass a function somewhere (a callback, an event listener, a timeout) and you want to make sure `this` stays what you intend it to be.

* * *

## One More Thing Worth Knowing

Arrow functions ignore all of this. They don't have their own `this`. They inherit it from the surrounding scope and `call()`, `apply()`, and `bind()` cannot change that.

```javascript
const person = {
    name: "Alice",
    greet: () => {
        console.log(this.name); // undefined, always
    }
};

person.greet();
```

Arrow functions are great in many situations, but if you need `this` to refer to the object, use a regular function.

* * *

## Conclusion

Once you stop thinking of `this` as something mysterious and start thinking of it as "who called this function," the rest follows. `call()` and `apply()` let you pick the caller. `bind()` locks one in for good.
