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
constcollegeGroup={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 undefinedconsole.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.
Arrow function does't have "arguments" like normal function
What is special object "arguments" in Javascript ?
In JavaScript, regular functions have a special object called arguments. This object is like an array that holds all the values passed into the function when it's called, even if those values weren't defined as parameters in the function's declaration.
See below example:
Arrow functions have no super
Example of "super"
So arrow functions do not have super. If accessed, it’s taken from the outer function. For instance:
Now, use following in-place of arrow function:
setTimeout(function(){super.stop()},1000);
And this would give error SyntaxError: 'super' keyword unexpected here
Related to Inheritance, but worth to share here, and you can think why both print the same ?
Answer: The parent `constructor` always uses its own field value for "this", not the overridden one.
Example:
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 ?
function AplusB() {
const [a, b] = arguments;
return a + b;
}
console.log(AplusB(1, 2));
class Animal {
constructor(name) {
this.name = name;
}
stop() {
console.log("Animal's stop() is exectuted")
}
}
class Rabbit extends Animal {
stop() {
setTimeout(() => super.stop(), 1000); // call parent stop after 1sec
// setTimeout(function() { super.stop() }, 1000)
console.log("Rabbit's stop() is exectuted")
}
}
// Run
const myAnimal = new Rabbit("Roocca");
myAnimal.stop() //
class Animal {
name = 'animal';
constructor() {
console.log(this.name);
}
}
class Rabbit extends Animal {
name = 'rabbit';
}
new Animal(); // animal
new Rabbit(); // animal
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;