What the fuck "this" is ?
Trying to understand "this"
Regular Function
In regular function "this" would reference to on which that function is called, otherwise "this" will be global ( in browser "window").
In case, of call/apply/bind, this
will refer to object on which that function/method is called
Arrow Function
Arrow functions are special: they donât have their âownâ this
. If we reference this
from such a function, itâs taken from the outer ânormalâ function (aka outer lexical environment).
Consider the following example, and see how "this" behave differently for regular and arrow function
const collegeGroup = {
title: "King's Sqad",
students: ["Azeem", "Pal", "PK"],
displayList() {
this.students.forEach((student) => {
// Takes 'this' from displayList() function (outer lexical scope)
console.log(`${this.title} - ${student}`);
});
},
displayListV2() {
this.students.forEach(function (student){
//forEach runs functions with this=undefined by default, so 'this' it will be undefined
console.log(`${this.title} - ${student}`);
})
}
}
collegeGroup.displayList() // ??
collegeGroup.displayListV2() // ??
So arrow function does't have "this", means they can't be used as constructor and can't be called as "new" âșïž
Again, arrow â
does't have "this", so .bind(this)
does't create any binding for arrow function and lookup of "this" will look into outer lexical environment.
Related to Inheritance, but worth to share here, and you can think why both print the same ?
class Animal {
name = 'animal';
constructor() {
console.log(this.name);
}
}
class Rabbit extends Animal {
name = 'rabbit';
}
new Animal(); // animal
new Rabbit(); // animal
Answer: The parent `constructor` always uses its own field value for "this", not the overridden one.
Example:
const bankAccount1 = {
name: "ABC 1",
display: function() {
console.log(this.name);
// Inner function as normal function
const innerDisplay = function() {
console.log(this.name);
// callback function as normal function (*)
setTimeout(function() { console.log(this.name); }, 0)
};
innerDisplay();
}
};
const bankAccount2 = { name: "ABC 2" };
bankAccount2.newDisplay = bankAccount1.display;
Question: 1 can we tell the output of bankAccount1.display();
?
Question: 2 can we tell the output of bankAccount2.newDisplay();
?
Question: 3 Change line (*)
to use arrow function as setTimeout(function() { console.log(this.name); }, 0)
and then tell the output of above two questions ?
Last updated