Function Context
Each function has an execution context which is exposed to the function via the this
keyword. You can explicitly bind a function to an execution context using Function Instance Methods call
, apply
and bind
.
const account = { balance: 100, } function displayBalance () { console.log(this.balance); } displayBalance(); displayBalance.bind(account)();
The
bind()
method creates a new function that and sets thethis
keyword 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 thethis
to reference the provided value as execution context. If the function takes in more arguments, those arguments can be passed (in order) following the first 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 execution context, 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
, andbind
methods, which generally rely on establishing a scope.