Function Context

Each function has an execution context which is exposed to the function via this keyword. You can use Function Instance methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) call, apply and bind to provide the execution context.

const account = {
  balance: 100,
}

function displayBalance () { 
  console.log(this.balance); 
}

displayBalance();
displayBalance.bind(account)();

The bind() method creates a new function that, when called, has its this keyword set to the provided value.

function greet() {
  console.log(`Welcome to ${this.name}`);
}

const cs280 = { name: "Full-Stack JavaScript" };
const cs226 = { name: "Data Structures" };

const greet280 = greet.bind(cs280);
const greet226 = greet.bind(cs226);

greet280();
greet226();

The calls() method calls a function and sets its this to the provided value. If the function takes in arguments, those arguments can be passed (in order) following the this argument.

const account = {
  balance: 100,
}

function deposit (amount) { 
  this.balance += amount; 
}

function withdraw (amount) { 
  this.balance -= amount; 
}

deposit.call(account, 50);
withdraw.call(account, 20);

console.log(account.balance);

The apply() method calls a function with a given this value, and the function arguments are provided as an array (or an array-like object).

const stats = {
  max: Number.MIN_SAFE_INTEGER,
  min: Number.MAX_SAFE_INTEGER
}

function max(...args) { 
  for(let i = 0; i < args.length; i++) {
    if (this.max < args[i]) {
      this.max = args[i];
    }
  }
}

function min(...args) { 
  for(let i = 0; i < args.length; i++) {
    if (this.min > args[i]) {
      this.min = args[i];
    }
  }
}

const numbers = [5, 6, 2, 3, 7];
max.apply(stats, numbers);
min.call(stats, ...numbers);
console.log(stats);

Arrow functions are not suitable for call, apply and bind methods, which generally rely on establishing a scope.