Arrow Function Expressions - The Basics
Tags: javascript, codenewbie, es6
Published: 2020-07-13 16:59:56

ES6, or ECMAScript 2015, brought us many great changes to the language of JavaScript. One such feature is **Arrow Functions**. That's what we'll dive into in this article - get to reading!

## What is an Arrow Function Expression?

An Arrow Function Expression is simply a new syntax to write function expressions as we've done before. In a lot of cases it can be much shorter to write which is great. If your task requires less typing you'll get more done in the same amount of time! 

Granted you understand it - which I most certainly _did not_ in my first encounters with the mighty `=>`.

Here's a very basic example (which there will be more of):

```js
/* * These are equivalent * */
// ES5
function func() {
  console.log('Function Expression example.')
}
func()
// ES6
const arrow = () => {
  console.log('Arrow Function Expression.')
}
arrow()
```

There are multiple aspects to the usage of Arrow Functions such as when it's best to use and not use them and some small gotchas on when they behave differently than an normal Function Expression. We won't cover them all here but we will cover some of the bigger ones.

## Which is better?

Wrong question to ask. You can accomplish your task using either method. People have opinions on this subject all around - but lets face it that will never change.

However, there are certain scenarios where a strong case can be made to use or _not use_ an Arrow Function.

#### When to Use

- When your resulting code will be shorter and more concise
- When your code becomes more readable
- When you feel like it!

#### When _not_ to Use

- As an object method directly
- When your resulting code isn't any shorter or concise
- When your code can become more confusing or hard to read and understand
- When you **do not** feel like it!

Keep in mind it largely comes down to personal preference on what you believe is more readable, more concise, less confusing, etc. As mentioned there are a couple things to be aware of when choosing which route to take.

#### Arrow Function: To code or not to code?

One big item to know is Arrow Functions are **_lexically bound_**. Let's take a look at a couple examples first:

```js
// ES5
var person = {
  name: 'Foo Bar',
  logName: function logName() {
    setTimeout(function() {
      console.log(this.name)
    }.bind(this), 1000)
  }
}
```
In order for the `logName()` method to actually log out the `name` property we must ensure the `setTimeout` binds `this`. We see that it is chained at the end of `setTimeout` - if we did not do that then `this` would actually be `undefined` since the callback function of `setTimeout` _does not have its own_ `this`. We explicitly bind it to the `this` of `logName` which is of course `person`.

```js
// ES6
var person = {
  name: 'Foo Bar',
  logName: function logName() {
    setTimeout(() => {
      console.log(this.name)
    }, 1000)  // No binding of 'this'
  }
}
```
This time with Arrow Functions we do not have to ensure binding of `this` to properly log it. IN THIS SCENARIO. (Gotcha comin' up...)

The catch here is that **Arrow Functions _cannot_ be bound to a `this`** so it will go up in scope to find the value of `this` in the context which it was called - AKA **_lexically bound_**.

It's not recommended to use Arrow Functions **directly** as object methods like the following:

```js
var person = {
  name: 'Foo Bar',
  logName: () => {  // => instead of function expression
    setTimeout(() => {
      console.log(this.name)
    }, 1000)
  }
}
```
Now `this.name` will return `undefined`. It's a little confusing but a key thing to remember is that again an Arrow Function will not have a `this` attached to itself. I like to think of Arrow Functions just passing the buck. 

The `console.log` tries to evaluate `this` so it goes to `setTimeout` 
- it says "I don't know a `this` maybe try to ask `logName`"
- we get to `logName` (which is also defined as an => so it cannot bind a `this`) and ask and it says "`this` doesn't ring a bell, maybe ask `person`?" 
- now we ask `person` and it's like "Hey I don't have any property called `this` I can't help."

Eventually we get all the way to the global `Window` object because that's the default when `this` isn't bound to anything in the context which we called it.

## Why use an Arrow Function?

Okay, that was confusing. `this` in relation to Arrow Functions is arguably the hardest thing to grasp. So let's talk about something easier to grasp and results in some clean looking code.

As mentioned, Arrow Functions can result in much shorter, cleaner code for us and especially in short function definitions or when using `map` or `reduce`.

Let's take a look.

```js
// ES5
function addTwoNums(x, y) {
  return x + y
}

// ES6
const addTwoNums = (x, y) => {
  return x + y
}
```
Doesn't look any shorter in ES6, right? One great feature of Arrow Functions is if we have one statement and want to return we don't use the {} or the `return` keyword.
```js
const addTwoNums = (x, y) => x + y
```
There's an implicit return when no braces or `return` is present with an Arrow Function. This really helps when it comes to the readability of a `map` or `reduce` usage.
```js
const nums = [1, 2, 3]

const doubledNums = nums.map(num => num * 2)
```
You may have noticed this time when using the Arrow Function in `map` we didn't put parenthesis around the parameter.

When there is **only one** parameter for an Arrow Function the parenthesis are _optional_.

So parenthesis can be optional and in certain scenarios the brackets and `return` can be omitted providing us multiple ways to write the same code. Going for the shortest code is usually what I would do - but again, personal preference.
```js
/* * These are ALL equivalent * */
// ES5
const doubledNums = nums.map(function(num) {
  return num * 2
})
// ES6
const doubledNums = nums.map((num) => {
  return num * 2
})
// ES6: No brackets - implicit return
const doubledNums = nums.map((num) => num * 2)
// ES6: Single parameter - no parameter parenthesis
const doubledNums = nums.map(num => num * 2)
```
Arrow Functions have more characteristics and gotchas than listed here but these are the basics I focused on to get a grasp. Once you get an understanding of these concepts take a peek at the [MDN Arrow Functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) page. You'll find plenty more use cases and confusing things to learn! 

Don't get me wrong - I keep saying confusing because it's true! I learn more each day - new things I hadn't heard of or known and how my understanding of something wasn't quite right. Let me know in the comments if there's an explanation here that isn't quite right or if there's an interesting gotcha you know of.

I still love JavaScript and this Tweet speaks to that pretty well!

{% twitter 1281985733079764993 %}