Difference between arrow functions and regular functions
Tags: javascript, beginners, codenewbie
Published: 2020-09-26 06:59:18

---
title: Difference between arrow functions and regular functions
published: true
date: 2020-09-25 14:00:00 UTC
tags: javascript, beginners, codenewbie
canonical_url: https://nimblewebdeveloper.com/blog/arrow-functions-vs-regular-functions
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/bnke0aesjhb63qqg39dp.png
---

## The difference between regular functions and arrow functions

ES6 and subsequent ECMAScript releases have featured the **arrow** function, amongst other things. The arrow function seems to be one of the features that causes much confusion and takes some time to learn.

There are 3 key differences between an arrow function and a regular (named) function.

First, we'll go over what each type of function is, then I'll quickly show you the differences. We're only looking at the differences in terms of how they might affect you day-to-day. For a more in-depth look, Mozilla has a good [reference article on arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions).

A regular (named) function in javascript looks like this;

```javascript  
function formatName(firstName, lastName) {  
  return firstName + " " + lastName;  
}  
  
```

And an arrow function might look like this;

```javascript  
const formatName = (firstName, lastName) => {  
  return firstName + " " + lastName;  
}  
  
```

## The differences

### 1. "this"

An arrow function does not have it's own `this` keyword. Instead, `this` is bound to the parent `this`. In the case where the arrow function is executed in the global context (it has no parent function/scope), `this` will be bound to the global object (`window` in the browser or `globalThis` in node).

#### When is this useful?

This is particularly helpful when you have some function whose `this` you might need to access from within an inner function. For example consider this pattern. (It's a bit contrived, but it shows how useful an arrow function can be when you need to access parent this).

```javascript  
// Let's create a controller to manage the value of some counter  
// when a button is pressed  
function ButtonController() {  
  // initialise the count value  
  // here "this" is the ButtonController instance  
  this.countValue = 0;  
    
  // create an arrow function to increase out counter  
  // within the arrow function "this" refers  
  // to the same "this" as above  
  const increaseCount = () => {  
    this.countValue += 1;  
  }  
    
  // As an example, this would be how we would have to do  
  // the same thing, without arrow functions  
    
  // we capture the parent "this" in some variable  
  var \_this = this;  
  function decreaseCount() {  
    // \_this is now available in the scope of decreaseCount  
    \_this.countValue -= 1;  
  }  
    
  return {  
    increaseCount,  
    decreaseCount,  
    get countValue() {  
      return this.countValue;  
    }  
  }  
}  
  
const controllerInstance = SomeController();  
  
// And we could bind this method to the on click event of a button  
controllerInstance.increaseCount();  
  
  
```

In the above example, `increaseCount` is an _arrow function_, and can easily access `this` from the `ButtonController` instance.

In contrast, `decreaseCount` is a named function, and to access `this` from the `ButtonController` instance, we have to save it to a variable (`_this`) and then reference it inside.

If you've done much with jQuery back in the day, this pattern might look familiar to you (capturing parent `this` for reuse inside a closure).

### 2. Implicit return

One of (in my opinion) the _best_ things about an arrow function is **implicit returns**.

What is an implicit return? Take the example at the top of the post. If we have a function that is really only a one-liner, it'd be nice not to have to write out the curly brackets and `return` statement, right?

Well, arrow functions allow us to do that!

```javascript  
// Instead of writing this function like this:  
const formatName = (firstName, lastName) => {  
  return firstName + " " + lastName;  
}  
  
//We can make use of implicit returns instead  
const formatName = (firstName, lastName) => firstName + " " + lastName;  
  
```

If your arrow function is written _without_ the curly brackets, it will implicitly (by default) return whatever comes next.

#### When is this useful?

Implicit returns from arrow functions becomes especially useful when working with array methods or callbacks.

Let's see some examples;

```javascript  
//Let's make an array of fruit.  
const fruitArray = ["Apple", "Banana", "Orange"];  
  
//Now we want an array of fruit but all lower case  
//Here we will use Array.map, and make use of the implicit return  
//from the arrow function that we pass as the callback  
const fruitArrayLowerCase = fruitArray.map(fruit=>fruit.toLowerCase());  
  
//The same thing without an arrow function would look like  
const fruitArrayLowerCasae = fruitArray.map(function(fruit) {  
  return fruit.toLowerCase();  
});  
  
  
//Imagine we need to chain a couple together:  
const fruitArrayFiltered = fruitArray  
  .map(fruit=>fruit.toLowerCase())  
  .filter(fruit=>fruit.charAt(0) === "a");  
  
```

Quick note:

If you want to return an **object literal** from your arrow function with an implicit return, you'll need to wrap it in brackets (parentheses). This is because passing a "curly" bracket to the arrow function looks like a function body, not a return value.

Example;

```javascript  
// The following function returns an object literal with  
// the two arguments as properties  
const myRegularFuncThatReturnsAnObject = function(a,b) {  
  return {a,b};  
}  
  
// To do the same with an arrow function, we need to wrap  
// the return value in brackets "(" ")"  
const myImplicitReturnFunc = (a,b) => ({a,b});  
  
```

### 3. Always anonymous

The third major difference between arrow functions and regular functions is that arrow functions are always anonymous. They _cannot_ be named. Whereas a regular function created with the `function` keyword can be named or anonymous (`function myFunc() {... }` vs `function() { ... }`), arrow functions are always anonymous.

Most of the time, this isn't a problem, as function naming is often only important when being passed to an event listener `addEventListener('click', myFunc)` so it can be removed again or similar.

The one main way that this impacts me is usually to do with _hoisting_. If you're not sure how hoisting works, the quick version is this;

Named functions are hoisted to the top of the current scope.

What does this mean? It means you can call a named function in your script higher up that where it is declared (within the same scope).

For example

```javascript  
// In this first example, we're using a named function, \*before\*  
// it's declared. This is because hoisting allows us to call  
// any named function within the same scope, despite the fact  
// that the function isn't declared until the end of the scope  
function initMyComponent1() {  
    
  // This works  
  this.addEventListener('click', handleComponentClick);  
    
  // handleComponentClick is a named function and thus  
  // it is hoisted to the top of initMyComponent1 scope  
  function handleComponentClick(e) {  
    // Do something  
  }  
    
}  
  
// In this second example, we're trying to use an anonymous  
// function \*before\* it's been declared  
// This will throw an error!  
function initMyComponent2() {  
   
  // THIS WILL FAIL!  
  this.addEventListener('click', handleComponentClick);  
    
  const handleComponentClick = (e) => {  
    // Do something  
  }  
}  
  
```

This largely only affects how you structure your file, but handy to know!

## Limitations

Just like anything, arrow functions are good in moderation & there are some cases where you _don't_ or _can't_ use them!

### 1. Use as methods or constructors

Arrow functions _shouldn't_ be used as methods. That's not to say you _can't_ use them as methods, but they're not best suited. This [example from Mozilla demonstrates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Arrow_functions_used_as_methods) why quite nicely. Essentially, as arrow functions don't have their own `this`, they can't access any other properties from a parent object.

Arrow functions _can't_ be used as constructors, and will throw an error if you try.

### 2. call, apply & bind

Because arrow functions use `this` from the scope that they were created in, using call, apply & bind with arrow functions can lead to some unexpected results, again I'm going to defer to [Mozilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#call_apply_and_bind) on that one because, well, it's boring.

## When to use an arrow function?

When should you use an arrow function? Good question!

An easy rule of thumb; if you _don't_ need access to the local `this` within your closure, go with an arrow function.

For example, simple utility functions, pure functions etc, an arrow function will do the trick.

A great use for arrow functions is with `setTimeout`, `setInterval`, and `addEventListener`. These methods will execute regular function callback with the global or `window` scope. Which can often lead to strange behaviours when the callback is executed.

```javascript  
// This won't work, as the addEventListener callback is  
// executed on the global (window) scope  
// obj.count is always 1  
const obj = {  
  count: 1,  
  addEventListener: function(el) {  
    el.addEventListener('click', function() {  
      this.count ++;  
    });  
  }  
}  
  
// This will work as expected, the arrow function is created  
// with the obj scope, and obj will be incremented  
const obj = {  
  count: 1,  
  addEventListener: function(el) {  
    el.addEventListener('click', ()=>{  
      this.count ++;  
    });  
  }  
}  
  
```

## When to use a regular, or a regular named function

When should you use a regular (or a named) function? There are a few cases where you definitely want to use a regular function;

- You need the function's `this` or `super` access
- An object constructor
- An object method\*
- If you want to use `yield` within the function body
- You want to use `call`, `apply`, or `bind`

\*You can use either type of function for an object method, but it will depend on your use case.