Understanding Arrow Functions: Syntax, Features, and Use Cases
Tags: javascript, tutorial, webdev, beginners
Published: 2023-07-09 17:00:15

1. [Introduction](#Introduction)
2. [Features of an arrow function](#Features)
3. [Syntax Variations for Declaring Arrow Functions](#Syntax)
     - [Arrow functions with parameters.](#functions with parameters)
     - [Arrow functions without parameters.](#functions without parameters)
     - [Arrow functions with default parameters](#functions with default parameters)
     - [Arrow functions as Expressions.](#function as expression)

4. [Arrow function and "this" keyword??](#this keyword)
5. [Other features of arrow functions](#other features)

**Introduction<a id="Introduction"></a>**
Functions are a fundamental part of JavaScript as they enable developers to break down complex tasks into smaller, manageable units. There are two major syntaxes used to define functions in JavaScript. These are the regular function syntax and the arrow function syntax. 

The regular function has been a part of JavaScript since its inception. However, the arrow function was introduced in ECMAScript 2015 (ES6) and provides a more concise way to define functions compared to regular function expressions. It also has some features that makes it different from regular functions.

In this article, we will talk about how arrow functions work, including their advantages and use cases.  We would also discuss the syntax variations in arrow functions and how they work with bindings in JavaScript.

**Features of an arrow function<a id="Features"></a>**
When declaring a function with the regular function syntax, you would have;

```javascript
function addition(num1, num2){
    sum = num1+num2;
    return sum
   }
```
Using the arrow syntax, the function can be written as;

```javascript
const addition = (num1 , num2) => {
    sum = num1 +  num2
     return sum
    }

```
From this example, we can point out some key features of arrow functions.

1. **_const_ declaration**: Instead of using the function keyword, we used the _const_ keyword to declare the arrow function. This ensures that the function reference cannot be reassigned.
You can also use the _var_ or _let_ keyword depending on your specific use case.

2. **Parameters**: Just like in regular functions, the parameters in arrow functions are declared within parentheses ().  In this example, num1 and num2 are the parameters specified within parentheses (num1, num2).

3. **Arrow (=>) notation**: The arrow notation separates the parameter list from the function body. It uses the equal sign (=) followed by a greater than sign (>), which forms an arrow. The arrow notation shows that the parameters are used to define the function.

4. **Function Body**: The function body contains the code that is executed when the function is called. It is enclosed in curly braces {}. For example, in the code, the function body calculates the sum of num1 and num2 and returns the result using the return statement.

```javascript
const addition = (num1 , num2) => {
    sum = num1 +  num2
     return sum
    }

```
If the function body only has a return statement, you can even have a shorter function expression.

```javascript
const addition = (num1 , num2 ) => {num1 +  num2}

```
 This is known as _Implicit Return_. It means that the value of the expression is automatically returned without using the _return_ keyword

**Syntax Variations for Declaring Arrow Functions<a id="Syntax"></a>**

Arrow functions can be defined using different syntax. This depends on the type of function and the context in which it is being used. Here are some examples.

**Arrow functions with parameters:<a id="functions with parameters"></a>**
Just like in the previous code snippet, you can declare an arrow function with parameters 

```javascript
const addition = (num1 , num2 ) => {
    const sum = num1 +  num2
     return sum
   }
```
   
If the function has only one parameter, you can omit the parentheses.  For example,

```javascript
const displayNum = num1  => {
    const Num= num1
     return Num
   }
```

**Arrow functions with default parameters:<a id="functions with default parameters"></a>**
Default parameters allow you to assign default values to function parameters in case no argument is passed when invoking the function. 
Arrow functions support default parameters in the same way as regular functions. For example;

```javascript

const multiply = (a, b= 1) => {
    return a * b;
  };
 
  console.log(multiply(5));
  console.log(multiply(5, 2))
```

In the preceding code, we created a function “multiply” which takes two parameters, a and b, with b having a default value of 1. 
This means that if the value of b is not provided, then the function executes as 5*1. However, if a value is provided for b, for instance, 2, it uses the provided value. This would execute as 5*2.

**Declaring arrow functions without parameters:<a id="functions without parameters"></a>**
If a function doesn't take any parameter, then you can use empty parentheses. 

```javascript
const greeting = () => {
     console.log('Hello World');  
}
greeting();
```

**Arrow Function as Expressions <a id="function as expression"></a>**
You can also create an arrow function and use it as an expression. For example,

```javascript
let score = 83;

let remark= (score < 50) ?
  () => console.log('pass') :
  () => console.log('Fail');

remark();
```

This may be a bit confusing so let’s break down the code;

- In Line 1 we declare a variable named score and assign it a value of 83. This variable represents the score that we are passing to the function

- In Lines 2-5 we use a ternary operator to assign a value to the remark variable.
 The ternary operator checks if the score is less than 50. If the condition is met, it assigns an arrow function () => console.log("Pass") to the remark variable. Otherwise, it assigns an arrow function () => console.log("Fail") to remark.

Finally, we call the remark function, which will execute based on the value of the score. In this case, since the score is 83 (which is greater than 50), it will log 'pass' to the console.


**Arrow Function and "this" Keyword. <a id="this keyword"></a>**

In regular functions, the value of a "this" variable is determined by how the function is called or the object it is called upon. This is because regular functions have their own "this" binding and can change depending on the context in which it is invoked. For example

**Regular function**

```javascript
const student = {
  name: 'Grace',
  age: 12,
  year: 2,
  studentProfile: function() {
    return 'Hi, my name is ' + this.name + ' and I am in year ' + this.year + '.';
  }
};

student.studentProfile();
```


In the code snippet, we defined an object named ‘student’  with properties _name_, _age_, and _year_. It also has an inner function called _studentProfile_. 
The _studentProfile _is defined using the regular function syntax. Hence, it uses the “this” keyword to refer to the object it is called upon which is the student object in this case. The output would therefore be 

`Hi, my name is Grace  and I am in year 2`

However, in arrow functions, the ‘this’ keyword inherits its value from the surrounding (lexical) scope in which they are defined rather than how it is called. This means that the value of ‘this’ can change depending on the context in which the function is executed. For instance

**Arrow function**
```javascript
const student = {
    name: 'Grace',
    age: 12,
    year: 2,
    studentProfile: () => {
      return `Hi, my name is ${this.name} and I am in year ${this.year}.`;
    }
  };

	student.studentProfile();
```
As we mentioned, arrow functions do not have their own ‘this’ context. Instead, they inherit the "this" value from the surrounding scope, which is the global scope in this case. Therefore, _this.name_ and _this.year_ within the arrow function does not refer to the properties of the student object. Instead, they reference properties of the global object (for example, a window in a browser environment).
As a result, when executing this code snippet, the output would be;

`Hi, my name is undefined  and I am in year undefined.`

To correctly use the "`this`" keyword in this scenario, we would use a regular function instead of an arrow function.

```javascript
const student = {
  name: 'Grace',
  age: 12,
  year: 2,
  studentProfile: function() {
    setTimeout(() => {
      console.log(Hi, my name is ${this.name} and I am in year ${this.year}.);
    }, 1000);
  }
};

student.studentProfile();
```

In this example, the _studentProfile_ function is defined as a regular function and we used a global object, _setTimeout()_ with an arrow function as the callback. Therefore,  the arrow function would inherit the "this" value from the surrounding _studentProfile_ function. This would now correctly log :

`Hi, my name is Grace and I am in year 2
`
**Other features of Arrow functions. <a id="other features"></a>**

Although arrow functions provide many benefits, they also have some features which could be considered limitations. These features could affect the way your function executes, so it's important to be aware of them before making use of arrow functions. 

-  Calling arrow functions with the new keyword throws a _TypeError_. They also don't have access to the new.target keyword. Therefore they cannot be used as constructors. 

- Arrow functions do not have bindings to _this_, _arguments_, or _super_ keywords. Hence, they do not work with object methods that require access to the object's properties through these keywords.

- Arrow cannot be used to call parent class methods as they do not have access to the _super _keyword which is used for this purpose.

- Arrow functions don't support the use of  _yield_ keyword within their body therefore they cannot be directly created as generator functions.

**Conclusion**
Arrow functions are especially useful for creating concise function expressions. However, it's best to use regular functions or other constructs when working with features that are not compatible with arrow functions. By understanding and applying the strengths and limitations of arrow functions, you can make choices that would help improve your code's functionality.