Function Context
Inside a function, the value of this depends on how the function is called.
Since the following code is not in strict mode, and because the value of this is not set by the call, this will default to the global object, which is window in a browser.
function f1() {
return this;
}
// In a browser:
f1() === window; // true
// In Node:
f1() === globalThis; // true
In strict mode, however, if the value of this is not set when entering an execution context, it remains as undefined, as shown in the following example:
function f2() {
'use strict'; // see strict mode
return this;
}
f2() === undefined; // true
Method Calls
When a function is called on an Object, this binds itself to that object.
const person= {
firstName: "John",
sayHi() {
console.log(`Hi ${this.firstName}!`);
}
};
person.sayHi(); // Hi John
const greet = person.sayHi;
greet(); // Hi undefined
setTimeout(person.sayHi, 1000); // Hi undefined
setTimeout(function () {
person.sayHi();
}, 1000); // Hi John
setTimeout(person.sayHi.bind(person), 1000); // Hi John
Arrow Functions
Arrow Functions don't have this. They use the value of this from outer function.
const outerThis = this;
const func = () => {
console.log(this === outThis);
};
func(); // true
Using methods like call, apply, and bind won't have any effect on arrow functions. They simply ignore them.
call and apply
We can explicitly set this to a particular value using call and apply methods.
function sayHi() {
console.log(`Hi ${this.firstName}!`);
}
const person = {
firstName: "Jane"
}
sayHi.call(person); // Hi Jane
sayHi.apply(person); // Hi Jane
Difference b/w call and apply
call expects a comma-separated list while apply expectes an array.
const numbers = [10, 20, 30, 40, 50];
const slice1 = numbers.slice(1, 4);
const slice2 = numbers.slice.call(numbers, 1, 4);
const slice3 = numbers.slice.apply(numbers, [1, 4]);