Arrow functions in JavaScript (arrow functions)

In a previous post we saw everything about functions in javascript. In this post we'll dedicate a special space to arrow functions, which have a particular and quite interesting behavior. After reading this post, you'll have a deep knowledge of arrow functions in Javascript.
This type of function is like a shorthand for functions that simplifies code quite a bit and also has a particular behavior with this
. Let's look at the following function:
const square = function(number) {
return number * number;
}
First of all with an arrow function, we can save the word function in the declaration.
const square = (number) => {
return number * number;
}
It's already an arrow function, but it can be improved. In this case, since the return expression consists of a single line, square brackets and the word return are not necessary.
const square = (number) => number * number;
And as if that weren't enough, since only one parameter is received, we can also save the parentheses.
const square = number => number * number;
On the other hand, arrow functions, being a type of shorthand, behave very similarly to anonymous functions, that is, they do not have hoisting. In addition, arrow functions cannot be used in the declaration of class methods.
Now, arrow functions don't know what this
is, so they take it from the nearest scope. Let's look at the following code.
class MyMath
{
constructor(number) {
this.number = number;
}
square() {
console.log('Square is ' + this.number * this.number);
}
}
When running this code, we get the expected result.
(new MyMath(3)).square(); // Square is 9
Now let's see what happens when we add a self-invoking anonymous function and a self-invoking arrow function.
class MyMath
{
constructor(number) {
this.number = number;
}
square() {
(() => {
console.log('Square is ' + this.number * this.number);
})();
(function(){
console.log('Square is ' + this.number * this.number);
})()
}
}
When running the code we get the following result.
(new MyMath(3)).square();
// Square is 9
// Uncaught TypeError: Cannot read properties of undefined (reading 'number')
In the first case, the arrow function interprets the closest this, which is that of the class in question, and prints the result. In the second case, the self-invoking function, as it has hositing, is "moved" to the beginning of its scope, which is the same class where there is nothing! I don't know exactly where in the multiverse this function is located! Let's modify our example a bit with an object in the global space.
let myMath =
{
number: 3,
square() {
(() => {
console.log('Square is ' + this.number * this.number);
})();
(function(){
console.log('Square is ' + this.number * this.number);
})()
}
}
When running the code we get the following result.
myMath.square()
// Square is 9
// Square is NaN
Now, we can verify that the function is hoisted to the beginning of the script if we add a number definition at the beginning of the script.
window.number = 10
let myMath =
{
number: 3,
square() {
(() => {
console.log('Square is ' + this.number * this.number);
})();
(function(){
console.log('Square is ' + this.number * this.number);
})()
}
}
When running the code we get the following result.
myMath.square()
// Square is 9
// Square is 100
In conclusion, arrow functions don't have hoisting, so to invoke them, it's necessary to have declared them beforehand.