Introduction to JavaScript Arrow Functions
Tags: webdev, javascript, codenewbie, beginners
Published: 2019-07-31 08:25:40


*This post was originally published on [attacomsian.com/blog](https://attacomsian.com/blog/javascript-arrow-functions).*

---

Arrow functions, introduced in ES6/ECMAScript 2015, are a syntactically compact alternative to regular ES5 functions. They are undoubtedly one of the most loved features of ES6 and are widely used nowadays. Arrow functions introduced a new way to write concise functions.

Here is a function written in ES5 function syntax:

```javascript
function absolute(num) {
    return Math.abs(num);
}

absolute(-9);   //9
```

Now, here is the same function written using ES6 arrow function syntax:

```javascript
const absolute = (num) => {
    return Math.abs(num);
}

absolute(-9);   //9
```

If the function body contains just a single statement, we can even omit the brackets and write everything in one line:

```javascript
const absolute = (num) => Math.abs(num);
```

## Function Parameters

If there are no parameters, just add an empty parentheses before `=>`:

```javascript
const pi = () => Math.PI;
```

You can even replace empty parentheses with `_`:

```javascript
const pi = _ => Math.PI;
```

If you have one ore more parameters, just pass them in the parentheses:

```javascript
const abs = (num) => Math.abs(num); // on parameter
const sum = (a, b) => a + b;    // two parameters
```

In case of only one parameter, you can remove the parentheses completely:

```javascript
const abs = num => Math.abs(num);
```

## Concise vs Block Body

An arrow function can have either a **concise body** or the **block body**. If the function contains only a single statement, you can use a concise body. In a concise body, only the expression is specified which implicitly returns a value (without using `return` keyword):

```javascript
const multiply = (a, b) => a * b;
```

In a block body, you must use an explicit `return` statement:

```javascript
const multiply = (a, b) => {
    return a * b;
};
```

Look at the curly braces. They are required in a block body to wrap statements:

```javascript
const oddNumber = (num) => {
    if(num % 2 == 0) {
        return false;
    } else {
        return true;
    }
};
```

## Object Literals

If you are returning an object literal using the concise body, it must be wrapped in parentheses to avoid it being treated as a block body:

```javascript
const json = () => ({x: 2}); 
```

## `this` Keyword

In regular function expressions, the `this` keyword is bound to different value based on the **context** in which the function is called:

* A new object in case of a constructor.
* `undefined` in strict mode function calls.
* The parent object if the function is called as an object method.

For example, Here is a person object which has `fullName()` function:

```javascript
const person = {
    firstName: 'Mike',
    lastName: 'Lilly',
    fullName: function () {
        return `${this.firstName} ${this.lastName}`;
    }
};

person.fullName(); // Mike Lilly
```

Calling `fullName()` method of person object returns the full name of the person.

However, an arrow function does not have its own `this` and is **lexically** bound. It essentially means that the `this` scope is **inherited** from the code that contains the arrow function. So while looking up for `this` which is not present in the current scope, the ES6 arrow function will use the value of `this` in the scope in which it was defined. That is why the call to `fullName()` will not work and will return an undefined value:

```javascript
const person = {
    firstName: 'Mike',
    lastName: 'Lilly',
    fullName: () => {
        return `${this.firstName} ${this.lastName}`;
    }
};

person.fullName(); // undefined undefined
```

Become of this arrow functions are not suited to object methods. You should also not use them as constructors either to avoid errors.

## DOM Event Handling

Arrow functions can be a problem while handling events. DOM event listeners set `this` to be the target element. Now, if you use arrow function for callbacks, the `this` keyword won't be bound to the target element, but rather bound to its parent scope.

```javascript
const button = document.getElementsByTagName('button')
button.addEventListener('click', () => {
  this.classList.toggle('blur');
});
```

Now if you click the button, you will get a `TypeError` because `this` refers to `window` in this scope. If you need a **dynamic context** for callback function, a regular function expression is required:

```javascript
const button = document.getElementsByTagName('button')
button.addEventListener('click', function() {
  this.classList.toggle('blur');
});
```

## Conclusion

Arrow functions provide a new way of writing concise functions in ES6. They are shorter, have no binding of `this` keyword, implicitly return a value (when the concise body is used), and are widely used in modern codebases. Arrow functions are inappropriate as object methods, and cannot be used as constructors.


---

✌️ I write about **modern JavaScript, Node.js, Spring Boot**, and all things **web development**. [**Subscribe to my newsletter**](https://attacomsian.com/newsletter) to get web development tutorials & protips every week.

---

**Like this article?** [Follow @attacomsian on Twitter](https://twitter.com/attacomsian). You can also follow me on [LinkedIn](https://linkedin.com/in/attacomsian) and [DEV](https://dev.to/attacomsian).

---

<small>Photo by <a href="https://unsplash.com/@jannerboy62?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Nick Fewings</a> on <a href="/search/photos/arrow?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></small>