Demystifying JavaScript Arrow Functions | Envato Tuts+

Demystifying JavaScript Arrow Functions | Envato Tuts+

[ad_1]

Normal Functions

In JavaScript, normal functions can be defined or declared using the function keyword, followed by the function name, a pair of parentheses for parameters (if any), and the function body. 

For example:

1
function greeting() {
2
    return "Hello world";
3
}

greeting is a simple function that returns the string, “Hello World”. 

Function Parameters

Functions can accept zero, one, or multiple parameters, depending on your requirements.

A Function With Zero Parameters

1
function greeting() {
2
    return "Hello world";
3
}

A Function With One Parameter

1
function greeting(name) {
2
    return "Hello " + name;
3
}

A Function With Multiple Parameters

1
function greeting(firstName, lastName) {
2
    return "Hello " + firstName + " " + lastName;
3
}

Anonymous Functions

Anonymous functions are functions without a name. They are often assigned to variables or passed as arguments to other functions. An anonymous function looks like this:

1
let greeting = function() {
2
     return "Hello world";
3
};

Even though the function doesn’t have a name, you can invoke it with the variable it is assigned to, like this:

1
console.log(greeting())
2
// Hello world

Arrow Functions

Arrow functions provide a simplified and concise way of declaring functions, making the code readable.

The following attributes define an arrow functions.

  • Arrow functions use a fat arrow (=>) instead of the function keyword.
  • Arrow functions provide shorter function expressions.
  • An arrow function doesn’t create its own this, arguments, or super and, therefore, cannot be used as a method when creating objects.
  • You cannot use an arrow function to create new object instances since they lack the prototype property.

The syntax for an arrow function looks like this:

1
let myFunction = (p, p1, p2, ...pnth) => {
2
    // define function logic here
3
  };
4
  

To convert our previous example of the anonymous greeting function to an arrow function, we only need to remove the function keyword and add an arrow => before the function body. The greeting function as an arrow function would look like this:

1
let greeting = () => {
2
  return "Hello world";
3

4
}

If the function has no parameters, we can further simplify the expression by removing the braces and the parentheses. So our function will look like this. 

1
let greeting = () => "Hello World";

The parentheses cannot be omitted even if there are no parameters.

Functions With Parameters

If an arrow function takes in parameters, they are added inside the parentheses, just like in regular functions. 

1
let greeting = (name) => "Hello " + name ;
2

3
console.log(greeting("Esther")); //output  //Hello Esther

If we only have a single parameter like the above, we can shorten the function further by removing the parentheses. 

1
let greeting = name => "Hello " +name ;

An Arrow Function  With Multiple Parameters.

1
let greeting = (name,timeofDay ) =>  "Hello "+ name + ", How is your " + timeofDay ;
2
console.log(greeting("Esther","evening"));
3
// output // Hello Esther, How is your evening

Multiple Statements

Sometimes, functions have multiple expressions or statements; in this case, statements or expressions should be enclosed in curly braces. 

1
let greeting = (name, timeOfDay) => {
2
    let message = "Good " + timeOfDay + ", " + name + "!";
3
    let today = new Date();
4
    let dayOfWeek = today.toLocaleDateString('en-US', { weekday: 'long' });
5
    
6
    return message + " Happy " + dayOfWeek + "!";
7
};
8

9
console.log(greeting("Esther","morning"))

Here, we have added a message that gets the current day of the week using the Date object and returns a custom greeting message depending on the day.

The output will be:

1
Good morning, Esther! Happy Tuesday!

Implicit vs Explicit Return

We have written some examples which have utilized the concept of implicit and explicit return. Implicit return is seen when we use a single expression, and the result is returned automatically without using the return keyword.

Implicit return means that the return keyword is automatically implied; hence, there is no need for the curly braces and the return keyword. Our greeting function below uses implicit return.

1
let greeting = (name,timeofDay ) =>  "Hello "+ name + ", How is your " + timeofDay ;
2

3
greeting("Esther","evening")

Explicit return, on the other hand, involves using the return keyword to specify what should be returned. Let’s modify our greeting function to demonstrate explicit return. Add the curly braces and include the return statement.

1
let greeting = (name, timeOfDay) => {
2
    return "Good " + timeOfDay + ", " + name + "!";
3
};
4
greeting("Esther","morning")

Arrow Functions and this Context

Arrow functions don’t have their own this context. The enclosing scope determines the value of this. Consider the example below.

1
const myObject = {
2
    name:"Mike",
3
    grade:8,
4
    ArrowMethod : () => `${this.name}, ${this.grade}`
5
}
6

7
const result = myObject.ArrowMethod()
8
console.log(result) //output //undefined

The output will be undefined because since the arrow function is defined inside an object, the arrow function will capture the value of this from the enclosing context, i.e., window in a browser environment or global object in a Node JS  environment. And since the global scope doesn’t have a name or grade property, the output of this.name  and this.grade becomes undefined.

In a regular function, the value of this is determined by how the function is called, so using a normal function will give the intended results.

1
const myObject = {
2
    name:"Mike",
3
    grade:8,
4
    ArrowMethod : function() { 
5
       return  `${this.name}, ${this.grade}`;
6
    }
7
}
8

9
const result = myObject.ArrowMethod()
10
console.log(result) //output //Mike, 8

Benefits and Applications of Arrow Functions

Arrow functions in web development improve code readability and reduce unnecessary syntax. Other common situations where arrow functions are applicable are in functional programming and Javascript promises.

Using Arrow functions to Transform arrays

Arrow functions are commonly used in functional programming. Functional programming involves the use of higher-order functions such as map(), filter(), and reduce()

Using the map() Function

The map function is an inbuilt method that transforms an array into another by applying a specific operation on each element of the original array. For example, Suppose we have an array of names and need a custom greeting message for each name in the array.

1
let names = ["Alice", "Bob", "Charlie"];

Let’s write a function greeting and return a  custom greeting for each name in the names array . Without using arrow functions, the function would look like this:

1
let greeting = function (name, timeOfDay) {
2
    return "Good " + timeOfDay + ", " + name;
3
}
4

5

6
let timeOfDay = "evening"; 
7

8
let greetings = [];
9

10
for (let i = 0; i < names.length; i++) {
11
    greetings.push(greeting(names[i], timeOfDay));
12
}
13

14
console.log(greetings)

The output will be:

1
[
2
  'Good evening, Esther',
3
  'Good evening, Carol',
4
  'Good evening, Amber'
5
]

We can perform the same transformation using the map() function and arrow functions, reducing the syntax and making the code readable.

1
let greeting = (name, timeOfDay) =>  "Good " + timeOfDay  + ", "+ name;
2
let names = ["Esther" , "Carol" ,"Amber"]
3
let timeOfDay = "evening"
4

5
let greetings = names.map(name =>greeting(name,timeOfDay));
6

7
console.log(greetings)

Using the filter() Function

The filter() function is another inbuilt JavaScript method that creates a new array based on a condition passed on original array elements. For example, suppose we have an array of products and need to filter based on products with a rating of more than 3. 

1
const products = [
2
    { id: 1, title: "Product A", rating: 4 },
3
    { id: 2, title: "Product B", rating: 2 },
4
    { id: 3, title: "Product C", rating: 3 },
5
    { id: 4, title: "Product D", rating: 5 },
6
    { id: 5, title: "Product E", rating: 1 }
7
];

Let’s apply the filter() function on the products array.

1
const filteredProducts = products.filter(product => product.rating>=3);
2
console.log(filteredProducts);
3
// output
4
[
5
    { id: 1, title: 'Product A', rating: 4 },
6
    { id: 3, title: 'Product C', rating: 3 },
7
    { id: 4, title: 'Product D', rating: 5 }
8
  ]

As you can see, the code is short and will make debugging easier.

Arrow Functions in Promise Chains

When working with promises, arrow functions are shorter, making the promise chains more readable; this can be useful, especially when debugging.

A promise is an object returned by an asynchronous method. Promises are usually used when working with APIs and other asynchronous tasks that are time-consuming.

Consider the Promise below, which simulates an asynchronous event where each .then() joins the original array to the resulting array.

1
new Promise(function(resolve) {
2
    setTimeout(function() {
3
        resolve([]);
4
    }, 1000);
5
    })
6
    .then(function(result) {
7
        return result.concat("Apples");
8
    })
9
    .then(function(result) {
10
        return result.concat("Oranges");
11
    })
12
    .then(function(result) {
13
        return result.concat("Kiwi");
14
    })
15
    .then(function(result) {
16
        console.log(result);
17
    });

Using arrow functions, the code is compact and easier to read.

1
new Promise((resolve) => {
2
    setTimeout(() => resolve([]), 1000);
3
  })
4
    .then((result) => result.concat("Apples"))
5
    .then((result) => result.concat("Oranges"))
6
    .then((result) => result.concat("Kiwi"))
7
    .then((result) => {
8
      console.log(result);
9
    });

Limitations of Arrow Functions

One of the limitations of arrow functions is using them as methods in objects. Consider the example below, which shows how to calculate a person’s BMI given their weight and height. 

1
const personObject = {
2
  heightMeters: 1.63, 
3
  weight: 64,        
4
  result: () => {
5
    const bmi = this.weight / (this.heightMeters * this.heightMeters);
6
    
7
    console.log(`BMI`, bmi);
8
  }
9
};
10
const calculateBMI = personObject.result(); 
11

12
console.log(calculateBMI) //output BMI NaN

The value of this inside the arrow function will output the global this context, which, in my case, is the window in a browser environment. It won’t refer to the personObject because arrow functions do not establish their own this context.

In such a case, traditional functions are better suited. When we use a traditional function, we can use this to refer to the PersonObject.

1
const personObject = {
2
    heightMeters: 1.63, 
3
    weight: 64,        
4
    result: function()  {
5
      const bmi = this.weight / (this.heightMeters * this.heightMeters);
6
      console.log(this);
7
      //here `this` refers to personObject. 
8
      console.log(`BMI`, bmi);
9
    }
10
  };
11
  
12
  personObject.result();
13
// {heightMeters: 1.63, weight: 64, result: ƒ} 
14
// BMI 24.088223117166624

Another limitation is that arrow functions cannot create new Object instances. Let’s look at the example below, where we are attempting to create an object constructor using an arrow function.

1
const Student = (name, grade) => {
2
    this.name = name;
3
    this.grade = grade;
4
  }
5
  
6
  // Create instance of Student
7
  const student1 = new Student("Mike", 8);

The output will be:

1
Uncaught TypeError: Student is not a constructor

The error above is because arrow functions don’t have the prototype property, which is important for object instantiation. You should use normal functions to create object constructors and use them for object instantiation.

Level Up Your JavaScript With Tuts+

Conclusion

Arrow functions are helpful when we want simple and short syntax. They are also perfect for single-expression functions. Arrow functions are also perfect when working with arrays, Javascript callbacks and Promises.  It’s also important to note that arrow functions may not be suitable for some situations. Traditional functions are better suited, especially when you need named or constructor functions.

[ad_2]

We will be happy to hear your thoughts

      Leave a reply

      WebForgers
      Logo
      Enable registration in settings - general