# Understanding this, call(), apply(), and bind() in JavaScript

If you've ever stared at the word `this` in JavaScript and had no idea what it was referring to — you're not alone. It's one of the most confusing parts of the language for beginners. But once you crack it, everything starts to make sense.

Let's break it down simply, with examples you can run right in your browser console.

* * *

## What Is `this`?

Here's the simplest way to think about it:

> `this` **refers to whoever is calling the function.**

It's not about where the function was written. It's about **who triggered it** at the moment it runs.

Think of a function like a worker. `this` is the worker asking: *"Who hired me right now? I'll work for them."*

```javascript
[ Function ]
     ↑
     | "Who called me?"
     |
[ The Caller ] ← this = the caller
```

* * *

## `this` Inside Normal Functions

When you call a function on its own (not attached to an object), `this` refers to the **global object** — which is `window` in a browser.

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

greet(); // logs the window object (in a browser)
```

In **strict mode**, `this` inside a standalone function is `undefined` instead.

```javascript
"use strict";

function greet() {
  console.log(this); // undefined
}

greet();
```

> **Takeaway:** Standalone functions have unpredictable `this`. The magic happens when functions are attached to objects.

* * *

## `this` Inside Objects

When a function lives inside an object and is called through that object, `this` refers to **that object**.

```javascript
const user = {
  name: "Sarah",
  greet: function () {
    console.log("Hello, my name is " + this.name);
  },
};

user.greet(); // "Hello, my name is Sarah"
```

Here, `user` is calling `greet()`, so `this` is `user`. Simple!

Now what if we try to borrow that function?

```javascript
const greetFn = user.greet;
greetFn(); // "Hello, my name is undefined" ⚠️
```

The function lost its connection to `user`. It's no longer being called *through* an object, so `this` no longer knows who it belongs to.

This is exactly the problem that `call()`, `apply()`, and `bind()` solve.

* * *

## `call()` — Borrow a Function and Run It Now

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

```javascript
function introduce(city, country) {
  console.log(`I'm ${this.name} from ${city}, ${country}.`);
}

const person = { name: "Carlos" };

introduce.call(person, "Madrid", "Spain");
// "I'm Carlos from Madrid, Spain."
```

**Syntax:**

```javascript
functionName.call(thisValue, arg1, arg2, ...)
```

You pass the object you want as `this` first, then the arguments one by one.

### Borrowing a method between objects

```javascript
const dog = {
  name: "Buddy",
  describe: function () {
    console.log(this.name + " is a good dog.");
  },
};

const cat = { name: "Whiskers" };

dog.describe.call(cat); // "Whiskers is a good dog."
```

`cat` borrowed `dog`'s method using `call()`. The function ran as if it belonged to `cat`.

* * *

## `apply()` — Like `call()`, but Arguments Go in an Array

`apply()` works exactly like `call()`, with one difference: **you pass arguments as an array** instead of one by one.

```javascript
function introduce(city, country) {
  console.log(`I'm ${this.name} from ${city}, ${country}.`);
}

const person = { name: "Aisha" };
const details = ["Lagos", "Nigeria"];

introduce.apply(person, details);
// "I'm Aisha from Lagos, Nigeria."
```

**Syntax:**

```javascript
functionName.apply(thisValue, [arg1, arg2, ...])
```

### When is `apply()` useful?

When your arguments are already in an array — like data coming from an API or user input — `apply()` saves you from spreading them manually.

```javascript
const numbers = [3, 7, 1, 9, 4];
console.log(Math.max.apply(null, numbers)); // 9
```

*(We pass* `null` *here because* `Math.max` *doesn't use* `this`*.)*

* * *

## `bind()` — Create a New Function with `this` Locked In

Unlike `call()` and `apply()`, `bind()` **does not run the function immediately**. Instead, it returns a brand new function where `this` is permanently set to whatever you choose.

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

const player = { name: "Jordan" };

const greetJordan = greet.bind(player);

// Nothing ran yet. We stored the bound function.

greetJordan(); // "Hello, I'm Jordan"
greetJordan(); // "Hello, I'm Jordan" (still works later)
```

**Syntax:**

```javascript
const newFn = functionName.bind(thisValue, arg1, arg2, ...)
```

### Why is `bind()` useful?

It's especially handy when passing methods as callbacks, where the original `this` would otherwise be lost.

```javascript
const timer = {
  message: "Time's up!",
  start: function () {
    setTimeout(this.ring.bind(this), 1000);
  },
  ring: function () {
    console.log(this.message);
  },
};

timer.start(); // "Time's up!" (after 1 second)
```

Without `bind(this)`, the `setTimeout` callback would lose the reference to `timer`.

* * *

## `call` vs `apply` vs `bind` — Side by Side

| Feature | `call()` | `apply()` | `bind()` |
| --- | --- | --- | --- |
| Runs immediately? | Yes | Yes | No — returns a new function |
| How args are passed | One by one | As an array `[ ]` | One by one (at bind time or call time) |
| Returns | The function's result | The function's result | A new bound function |
| Best used when | You want to run it now with specific args | Your args are already in an array | You want to save it and call it later |

* * *

## Putting It All Together

```javascript
const doctor = {
  name: "Dr. Patel",
  diagnose: function (symptom, severity) {
    console.log(`${this.name} says: ${symptom} is ${severity}.`);
  },
};

const nurse = { name: "Nurse Kim" };

// call() — run now, pass args one by one
doctor.diagnose.call(nurse, "fever", "mild");
// "Nurse Kim says: fever is mild."

// apply() — run now, pass args as array
doctor.diagnose.apply(nurse, ["headache", "moderate"]);
// "Nurse Kim says: headache is moderate."

// bind() — save for later
const nurseCheck = doctor.diagnose.bind(nurse);
nurseCheck("fatigue", "severe");
// "Nurse Kim says: fatigue is severe."
```

* * *

## Practice Assignment

Work through these steps to solidify the concepts:

**1\. Create an object with a method using** `this`**:**

```javascript
const car = {
  brand: "Toyota",
  describe: function () {
    console.log("This car is a " + this.brand);
  },
};

car.describe(); // works as expected
```

**2\. Borrow that method using** `call()`**:**

```javascript
const bike = { brand: "Yamaha" };

car.describe.call(bike); // "This car is a Yamaha"
```

**3\. Use** `apply()` **with array arguments:**

```javascript
function showDetails(year, color) {
  console.log(`${this.brand} — ${year} — ${color}`);
}

const details = [2022, "red"];
showDetails.apply(car, details);  // "Toyota — 2022 — red"
showDetails.apply(bike, details); // "Yamaha — 2022 — red"
```

**4\. Use** `bind()` **and store the function:**

```javascript
const describeBike = car.describe.bind(bike);

// Call it whenever you need
describeBike(); // "This car is a Yamaha"
describeBike(); // still works!
```

* * *

## Quick Recap

*   `this` always refers to whoever is calling the function at runtime
    
*   Inside **objects**, `this` is the object itself
    
*   Standalone functions can lose `this` — that's where the three methods come in
    
*   `call()` — runs immediately, arguments passed one by one
    
*   `apply()` — runs immediately, arguments passed as an array
    
*   `bind()` — doesn't run immediately, returns a new function with `this` locked in
    

Master these three and you'll never feel confused by `this` again.

Happy coding! 🚀

* * *

> If you enjoyed this article, check out my other blogs on this profile.
> 
> 🔗 **Connect with me:**  
> [**LinkedIn**](https://linkedin.com/in/rajharsh03) | [**GitHub**](https://github.com/RajHarsh03) | [**X (Twitter)**](https://x.com/rajharsh03)
