In JavaScript, the execution context of a function is critical as it determines what the this
keyword refers to inside the function. This context can be manipulated using specific methods like call
, apply
, and bind
, which are part of the Function object’s capabilities.
this
and Function BindingWhen a function is invoked, JavaScript sets the value of this
based on the context of the invocation. However, this can be explicitly controlled using the bind
method.
bind
The bind()
method creates a new function that, when called, has its this
keyword set to the provided value.
const account = {
balance: 100,
}
function displayBalance() {
console.log(this.balance);
}
displayBalance(); // Undefined, because 'this' is not defined
displayBalance.bind(account)(); // 100, 'this' refers to 'account'
Here’s another example with different contexts:
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(); // "Welcome to Full-Stack JavaScript"
greet226(); // "Welcome to Data Structures"
call
The call()
method calls a function with a specified this
value and arguments provided individually.
const account = {
balance: 100,
}
function deposit(amount) {
this.balance += amount;
}
function withdraw(amount) {
this.balance -= amount;
}
deposit.call(account, 50); // account.balance is now 150
withdraw.call(account, 20); // account.balance is now 130
console.log(account.balance); // 130
apply
Similar to call
, the apply()
method calls a function with a specified this
value, but the arguments are passed as an array.
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); // Outputs: { max: 7, min: 2 }