# A tutorial to JavaScript Arrow Functions

> Learn JavaScript arrow function syntax, implicit returns, lexical this, rest parameters, and when a regular function is the better choice.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-04-29 | Updated: 2026-07-18 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/javascript-arrow-functions/

Arrow functions are a compact way to write function expressions.

They were added in ES2015. Their most important difference is not the shorter syntax: arrow functions do not create their own `this`.

See the [MDN arrow functions reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) for the complete syntax.

## Arrow function syntax

This regular function expression:

```js
const greet = function(name) {
  return `Hello, ${name}`
}
```

can be written as an arrow function:

```js
const greet = name => {
  return `Hello, ${name}`
}
```

Use parentheses for no parameters or multiple parameters:

```js
const getMessage = () => 'Hello'
const add = (a, b) => a + b
```

With exactly one simple parameter, parentheses are optional:

```js
const double = number => number * 2
```

Parameters with defaults, destructuring, or rest syntax need parentheses:

```js
const greet = (name = 'friend') => `Hello, ${name}`
const getName = ({ name }) => name
const sum = (...numbers) => numbers.reduce((total, number) => total + number, 0)
```

## Implicit return

An arrow function with an expression body returns that expression:

```js
const double = number => number * 2

double(4) //8
```

Add curly braces when you need multiple statements. Then use `return` explicitly:

```js
const double = number => {
  const result = number * 2
  return result
}
```

Wrap an object literal in parentheses for an implicit return:

```js
const createUser = name => ({ name })

createUser('Flavio') //{ name: 'Flavio' }
```

Without the parentheses, JavaScript treats the braces as the function body.

## Arrow functions use lexical `this`

An arrow function captures `this` from the surrounding scope. Calling it with a different receiver does not change that value.

This makes arrow functions useful inside callbacks:

```js
const counter = {
  value: 0,
  start() {
    setInterval(() => {
      this.value += 1
    }, 1000)
  }
}
```

The arrow callback uses the same `this` as `start()`.

Do not use an arrow function as an object method when you need `this` to refer to that object:

```js
const car = {
  model: 'Fiesta',
  manufacturer: 'Ford',
  fullName() {
    return `${this.manufacturer} ${this.model}`
  }
}

car.fullName() //'Ford Fiesta'
```

A regular method gets `this` from how it is called. An arrow function does not.

## Arrow functions in event listeners

In a DOM listener written with a regular function, `this` equals `event.currentTarget`:

```js
const link = document.querySelector('#link')

link.addEventListener('click', function(event) {
  this === event.currentTarget //true
})
```

An arrow listener inherits `this` from outside. Use `event.currentTarget` when you want the element:

```js
link.addEventListener('click', event => {
  console.log(event.currentTarget)
})
```

## Other differences from regular functions

Arrow functions also do not have their own:

- `arguments`
- `super`
- `new.target`

Use rest parameters instead of `arguments`:

```js
const logValues = (...values) => {
  console.log(values)
}
```

Arrow functions cannot be used as constructors:

```js
const Person = name => ({ name })

new Person('Flavio') //TypeError
```

They also cannot be generator functions.

Use arrow functions for short callbacks and lexical `this`. Use regular functions for constructors, generators, and methods that need a dynamic `this`.
