# Call, Apply, and Bind

These three methods are used to control the value of `this` inside a function. They allow you to borrow methods from one object and use them with another.

## 1. `call()`

The `call()` method invokes a function immediately with a specified `this` value and arguments provided individually.

**Syntax:** `func.call(thisArg, arg1, arg2, ...)`

```javascript
const person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}

const person1 = {
  firstName: "John",
  lastName: "Doe"
}

console.log(person.fullName.call(person1, "Oslo", "Norway"));
// Output: John Doe,Oslo,Norway
```

## 2. `apply()`

The `apply()` method is very similar to `call()`, but arguments are passed as an **array** (or an array-like object).

**Syntax:** `func.apply(thisArg, [argsArray])`

```javascript
const person = {
  fullName: function(city, country) {
    return this.firstName + " " + this.lastName + "," + city + "," + country;
  }
}

const person1 = {
  firstName: "John",
  lastName: "Doe"
}

console.log(person.fullName.apply(person1, ["Oslo", "Norway"]));
// Output: John Doe,Oslo,Norway
```

### Mnemonic
*   **C**all: **C**omma-separated arguments.
*   **A**pply: **A**rray of arguments.

## 3. `bind()`

The `bind()` method **does not** invoke the function immediately. Instead, it returns a **new function** where `this` is permanently bound to the first argument. You can execute this new function later.

**Syntax:** `const newFunc = func.bind(thisArg, arg1, arg2, ...)`

```javascript
const module = {
  x: 42,
  getX: function() {
    return this.x;
  }
};

const unboundGetX = module.getX;
console.log(unboundGetX()); // The function gets invoked at the global scope
// Expected output: undefined

const boundGetX = unboundGetX.bind(module);
console.log(boundGetX());
// Expected output: 42
```

### Partial Application
`bind()` can also be used for partial application (currying), where you preset some arguments.

```javascript
function multiply(a, b) {
  return a * b;
}

const multiplyByTwo = multiply.bind(null, 2);
console.log(multiplyByTwo(5)); // 10
```

[[programming/javascript/vanilla/javascript]]
[[programming/javascript/vanilla/this-keyword]]