JavaScript Arrow Function [In-Depth Tutorial]


JavaScript

Introduction to JS Arrow Function

Arrow functions, also known as "fat arrow" functions, are a new feature in JavaScript that provides a concise and more expressive syntax for defining functions. They were introduced in ECMAScript 6 (also known as ECMAScript 2015) and have become widely used in modern JavaScript code.

They have become a popular feature of the language, thanks to their concise syntax and ability to capture the lexical this value. Arrow functions are often used in place of traditional function expressions and can make your code more readable and easier to write.

Instead of the function keyword, it uses an arrow (=>) made up of an equal sign and a greater-than character (not to be confused with the greater-than-or-equal operator, which is written >=).

const power = (base, exponent) => {
  let result = 1;
  for (let count = 0; count < exponent; count++) {
    result *= base;
  }
  return result;
};

The arrow comes after the list of parameters and is followed by the function’s body. It expresses something like “this input (the parameters) produces this result (the body).”

In this article, we will explore the syntax and usage of JavaScript arrow functions, including how to use them as methods, constructors, and in combination with other functions.

 

Using arrow functions

Functions allow us to reduce repetition, and different approaches including the arrow function style make it easy to achieve this. As stated, arrow functions allow us to be concise in a simple manner. Let’s start with some examples to show how we can use arrow functions in JavaScript.

 

Taking a single argument

Here is an example of an arrow function that takes a single argument x and returns its square:

let square = x => x * x;

console.log(square(3));

Output

9

As you can see, the arrow function has a shorter syntax than a regular function. It does not have a function keyword, a pair of curly braces, or a return statement. Instead, it consists of the => operator (which is sometimes referred to as the "fat arrow"), followed by the function body.

 

Taking multiple arguments

If the function takes more than one argument, you need to enclose the arguments in parentheses. Let’s illustrate this by creating an arrow function that adds two numbers parsed to it.

let add = (x, y) => x + y;

console.log(add(3, 4));

Output

7

 

Structuring arrow functions

Depending on the structure of the code block, arrow functions can be shaped in different ways e.g. no curly braces, etc.

If the function body is a single expression, you can omit the curly braces and the return statement. The value of the expression will be returned automatically. Let’s show this by creating an arrow function that squares a number.

let square = (x) => x * x;

console.log(square(3));

Output

9

The above code is equivalent to let square = x => { return x * x; }.

If the function body consists of multiple statements, you need to enclose them in curly braces and use a return statement to specify the value to be returned.

To showcase this scenario, we will create an arrow function that adds and multiplies its argument and returns an array.

let addAndMultiply = (x, y) => {
    let sum = x + y;
    let product = x * y;
    return [sum, product];
};

console.log(addAndMultiply(3, 4));

Output

[ 7, 12 ]

 

Lexical this in arrow functions

An important aspect of arrow functions is that they behave differently from normal functions. The difference is subtle but important. Arrow functions do not have their own value of this. The value of this in an arrow function is inherited from the enclosing (lexical) scope.

Functions have a special variable this that refers to the object via which the method was invoked. As the value of this is dynamically given based on the function invocation, it is sometimes called dynamic this. A function is executed in two scopes-lexical and dynamic. A lexical scope is a scope that surrounds the function scope, and the dynamic scope is the scope that called the function (usually an object).

Consider this example:

    var greeter = { 
      default: "Hello ", 
      greet: function (names){ 
        names.forEach(function(name) { 
    console.log(this.default + name); //Cannot read property 
      'default' of undefined 
       }) 
      } 
    }     
    console.log(greeter.greet(['hello', 'world'])) 

We are passing a subroutine to the forEach() function on the names array. This subroutine has an undefined value of this, and unfortunately, it does not have access to this of the outer method greet. Clearly, this subroutine needs a lexical this,derive this from the surrounding scope of the greet method. Traditionally, to fix this limitation, we assign the lexical this into a variable, which is then accessible to the subroutine via closure.

We can fix the earlier example as follows:

    var greeter = { 
      default: "Hello ", 
      greet: function (names){ 
        let that = this 
        names.forEach(function(name) { 
          console.log(that.default + name);  
       }) 
      } 
    }     
    console.log(greeter.greet(['hello', 'world'])) 	

This is a reasonable hack to simulate lexical this. However, the problem with such hacks is that it creates too much noise for the person writing or reviewing this code. First, you have to understand the quirk of the behavior of this. Even if you understand this behavior well, you will need to continuously remain on the lookout for such hacks in your code.

Arrow functions have lexical this and do not require such a hack. They are more suited as subroutines because of this. We can covert the preceding example to use lexical this using the arrow function:

    var greeter = { 
      default: "Hello ", 
      greet: function (names){ 
        names.forEach(name=> { 
          console.log(this.default + name);   //lexical 'this' 
           available for this subroutine 
       }) 
     } 
    }     
    console.log(greeter.greet(['hello', 'world'])) 	

 

Benefits of arrow function

Arrow functions have a number of benefits and features that make them useful in various situations. Here are a few examples:

  • Arrow functions do not have their own this value. They inherit the this value of the surrounding scope. This makes them particularly useful in object-oriented programming, where this often refers to the object that the function belongs to.
  • Arrow functions do not have a arguments object. If you need to access the arguments passed to a function, you can use the rest operator (...) instead.
  • Arrow functions can be used as callbacks and passed as arguments to other functions. For example, you can use them with array methods such as map(), filter(), and reduce().

Here is an example that uses an arrow function as a callback in the map() method

let numbers = [1, 2, 3, 4, 5];
let squares = numbers.map((x) => x * x);

console.log(squares); // [1, 4, 9, 16, 25]

Output

[ 1, 4, 9, 16, 25 ]

This approach makes it a lot easier to read.

 

Summary

In conclusion, arrow functions are a concise and powerful feature of JavaScript that allow developers to write shorter and more expressive code. They are particularly useful when working with higher-order functions and in scenarios where the this keyword might be confusing. However, it's important to keep in mind that arrow functions behave differently than traditional functions in terms of their lexical this binding and cannot be used as constructors. Overall, arrow functions are a useful tool in any JavaScript developer's toolkit and can greatly improve the readability and maintainability of your code.

 

References

Arrow function expressions - JavaScript | MDN (mozilla.org)

 

Olorunfemi Akinlua

Olorunfemi Akinlua

He is boasting over five years of experience in JavaScript, specializing in technical content writing and UX design. With a keen focus on programming languages, he crafts compelling content and designs user-friendly interfaces to enhance digital experiences across various domains. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment