# Call, Bind and Apply in Javascript

If you write JavaScript, you've fought `this`. The confusion happens because we bring mental models from languages like Java or C++, where `this` is tied to the class it was written in. JavaScript doesn’t care where you *wrote* the function. It only cares about who called the function at runtime. A mental model I can think of is, look at the left of the dot. Lets look at an example.

```javascript
const service = {
  name: "Payment Gateway",
  start: function() {
    console.log(`Starting ${this.name}`);
  }
};

service.start(); 
```

Look at `service.start()`. Who is on the left of the dot? `service`. So, `this = service`.

```javascript
const startService = service.start;
startService(); 
```

Look at `startService()`. There is nothing to the left of the dot. It’s just a raw function call. The context is lost, `this` defaults to undefined, and your app crashes. To fix this, JavaScript gives us three methods on the `Function.prototype` to manually force the `this` context `call`, `apply`, and `bind`.

## 1\. CALL

`call` immediately fires the function, forcing `this` to be the first argument you pass. Any remaining arguments are passed individually.

```javascript
function logError(level, message) {
  console.log(`[${this.service}] ${level}: ${message}`);
}

const context = { service: "Auth" };
logError.call(context, "CRITICAL", "connection lost"); 
```

## 2\. APPLY

`apply` is exactly the same as `call`, but it takes the function's arguments as a single array.

```javascript
logError.apply(context, ["CRITICAL", "connection lost"]);
```

## 3\. BIND

`bind` doesn't execute the function immediately. Instead, it returns a new function with `this` permanently locked to the object you provided. This is how you fix the callback problem.

```javascript

const safeStart = service.start.bind(service);

setTimeout(safeStart, 1000); 
```

### writing the polyfills

To truly understand a system, you build it yourself. If we were to write these methods from scratch, how would the engine actually do it?

### The call Polyfill

trick is simple, temporarily attach the function to the target object as a property. Then call it. By doing this, the object is literally to the left of the dot.

```javascript
Function.prototype.myCall = function(context = globalThis, ...args) {
  
  const fnKey = Symbol('fn');
  
  
  context[fnKey] = this;
  
  const result = context[fnKey](...args);
 
  delete context[fnKey];
  return result;
};
```

**The apply Polyfill**

Almost identical to `call`, but we spread an array.

```javascript
Function.prototype.myApply = function(context = globalThis, argsArray = []) {
  const fnKey = Symbol('fn');
  context[fnKey] = this;
  
  const result = context[fnKey](...argsArray);
  
  delete context[fnKey];
  return result;
};
```

**The bind Polyfill**

`bind` needs to return a closure. When that closure is eventually called, it uses `apply` internally to execute the original function with the locked context.

```javascript
Function.prototype.myBind = function(context = globalThis, ...boundArgs) {
  const originalFn = this;
  
  return function(...executionArgs) {
    return originalFn.apply(context, [...boundArgs, ...executionArgs]);
  };
};
```

Mastering execution context moves you from randomly guessing why a callback broke, to deliberately architecting how your data flows through asynchronous boundaries.
