# Function Context

> Source: https://learn-typescript.org/function-context/
> Part of Learn TypeScript, free to read.

Functions in JavaScript run in a specific context, and using the `this` variable we have access to it.

All standard functions in the browser run under the Window context. Functions defined under an object or a class (another function) will use the context of the object it was created in. However, we can also change the context of a function at runtime, either before or while executing the function.

### Binding a method to an object

To bind a function to an object and make it an object method, we can use the `bind` function. Here is a simple example:

```typescript
let person = {
    name : "John"
};

function printName()
{
    console.log(this.name);
}
```

Obviously, we are not able to call `printName()` without associating the function with the object `person`. To do this we must create a bound method of the function printName to person, using the following code:

```typescript
let boundPrintName = printName.bind(person);
boundPrintName();    // prints out "John"
```

### Calling a function with a different context

We can use the `call` and `apply` functions to call a function as if it was bound to an object. The difference between the `call` and `apply` functions is only by how they receive their arguments - the `call` function receives the `this` argument first, and afterwards the arguments of the function, whereas the `apply` function receives the `this` argument first, and an array of arguments to pass on to the function as a second argument to the function.

For example, let’s call `printName` with `person` as the context using the `call` method:

```typescript
printName.call(person);      // prints out "John"
```

### call/apply vs bind

The difference between `call`/`apply` and `bind` is that `bind` returns a new function identical to the old function, except that the value of `this` in the new function is now the object it was bound to.  `call`/`apply` calls the function with `this` being the bound object, but it does not return a return a new function or change the original, it calls it with a different value for `this`.

For example:

```typescript
let boundPrintName = printName.call(person);    //boundPrintName gets printName's return value (null)
boundPrintName();                               //doesn't work because it's not a function, it's null

printName.bind(person);                         //returns a new function, but nothing is using it so it's useless
printName();                                    //throws error because this.name is not defined
```

Think of `call` as executing the return value of `bind`.

For example:

```typescript
printName.call(person);     //is the same as
printName.bind(person)();   //executes the function returned by bind
```

Or think of `bind` returning a shortcut to `call`.

For example:

```typescript
let boundPrintName = printName.bind(person); //is the same as
let boundPrintName = function()
{
    printName.call(person);
}
```
