Arrow functions

Write short functions with arrow syntax and implicit returns, and learn the differences that decide when not to use one.

  • Beginner
  • 7 min read
  • Updated 17 Oct 2026

What you will learn

  • Write arrow functions
  • Know when not to use an arrow
  • Use implicit returns, including returning an object
  • Use arrow functions as callbacks

Arrow functions are a shorter way to write function expressions. You will see them everywhere in modern JavaScript, especially as callbacks. They are not just shorter, though: they behave differently in a few ways that matter. This lesson covers the syntax and when an arrow is the wrong choice.

From function expression to arrow

Here is a function expression from the last lesson:

JavaScript
const square = function (n) {
  return n * n;
};

The same function as an arrow function:

JavaScript
const square = (n) => {
  return n * n;
};

console.log(square(4));
// 16

Drop the function keyword and put => (an "arrow") between the parameters and the body. Everything else works the same way: parameters, default values and return.

Implicit return

When the body is a single expression, you can leave out the braces and the return keyword. The arrow returns the value of the expression automatically:

JavaScript
const square = (n) => n * n;

console.log(square(5));
// 25

This is called an implicit return. It makes small functions very compact:

JavaScript
const add = (a, b) => a + b;
const isEven = (n) => n % 2 === 0;
const greet = (name = "friend") => `Hello, ${name}!`;

console.log(add(2, 3));
// 5
console.log(isEven(7));
// false
console.log(greet());
// Hello, friend!

The rule is simple: with braces, you need return; without braces, the expression is returned. Mixing them up is a common mistake:

JavaScript
const double = (n) => {
  n * 2;
};

console.log(double(4));
// undefined

The braces make a block body, so the calculation happens and is thrown away. Either remove the braces or add return.

Parameter shapes

The brackets around parameters are optional when there is exactly one parameter, and required otherwise:

JavaScript
const shout = text => text.toUpperCase();   // one parameter, brackets optional
const now = () => Date.now();                // no parameters, brackets required
const area = (width, height) => width * height; // two parameters, brackets required

Many teams always include the brackets, so adding a second parameter later does not mean rewriting the function, and code formatters such as Prettier add them by default. This course always includes them.

Returning an object

To return an object literal implicitly, wrap it in brackets. Otherwise the braces are read as a function body:

JavaScript
const makeUser = (name) => { name: name };
console.log(makeUser("Ada"));
// undefined

const makeUserFixed = (name) => ({ name: name });
console.log(makeUserFixed("Ada"));
// { name: "Ada" }

In the first version, JavaScript sees a block containing a label called name, which is valid but useless, and returns nothing. The brackets in the second version make it an expression. Lesson 13 covers objects.

Arrows as callbacks

Arrow functions shine when you pass a short function to another function:

JavaScript
const prices = [4, 10, 7];

const withVat = prices.map((price) => price * 1.2);
console.log(withVat);
// [4.8, 12, 8.4]

map() calls the arrow once for each item and collects the results into a new array. You will learn map() and its relatives in lesson 22. Compare the arrow with the older style:

JavaScript
const withVatOld = prices.map(function (price) {
  return price * 1.2;
});

Both work. The arrow version puts the important part, price * 1.2, front and centre.

You saw an arrow callback in lesson 1 too, passed to addEventListener:

JavaScript
button.addEventListener("click", () => {
  button.textContent = "Thanks!";
});

How arrows differ from regular functions

Arrow functions are not just shorthand. They leave out several features that regular functions have.

No own this

Regular functions get a value called this that depends on how they are called. Arrow functions do not have their own this; they use the this of the code around them. That makes arrows good for callbacks inside methods, and a poor choice for methods themselves:

JavaScript
const counter = {
  count: 0,
  increment() {
    this.count++;
    return this.count;
  },
  broken: () => {
    return this;
  },
};

console.log(counter.increment());
// 1

increment is a regular method, so this is counter. broken is an arrow, so this is whatever it was outside the object, never counter. Lesson 21 explains this fully. For now, use the method shorthand name() { ... } for object methods, not arrows.

Cannot be used with new

Regular functions can be called with new to create objects. Arrows cannot:

JavaScript
const Person = (name) => {
  this.name = name;
};

new Person("Ada");
// Uncaught TypeError: Person is not a constructor

Use a class for this, as lesson 36 shows.

No arguments object

Regular functions have a special arguments variable holding every argument passed. Arrows do not. Use rest parameters, (...args) => {}, instead; lesson 23 covers them.

Not hoisted

An arrow function is always an expression, usually stored in a const. Like any function expression, it cannot be called before the line that creates it.

When not to use an arrow

SituationUse
Short callbacks for array methods, timers and promisesArrow function
Event listener that does not need thisArrow function
Object methods that use thisMethod shorthand: name() {}
Creating objects with newA class
Top-level named functions in a fileEither; many teams prefer declarations for these
An event listener that uses this to mean the elementA regular function, or better, event.currentTarget

Arrow functions are a good default for small functions you pass around. When a function needs its own this, reach for a regular function or method.

Readability

Arrow functions can be written so compactly that they become hard to read. A few habits help:

  • Use an implicit return only when the expression fits comfortably on a line.
  • Give callbacks meaningful parameter names: (price) => price * 1.2, not (p) => p * 1.2, unless the meaning is obvious.
  • If a callback grows beyond a few lines, consider moving it into a named function and passing the name.
JavaScript
const applyVat = (price) => price * 1.2;
const withVat = [4, 10, 7].map(applyVat);
console.log(withVat);
// [4.8, 12, 8.4]

Notice that you pass applyVat without brackets. You are handing over the function itself for map() to call, not calling it yourself.

Summary

  • Arrow functions use (params) => body and are a shorter form of function expression.
  • A body without braces returns its expression automatically. With braces, you need return.
  • Wrap an object literal in brackets to return it implicitly: () => ({ ... }).
  • Arrows are ideal for short callbacks.
  • Arrows have no own this, no arguments, cannot be used with new and are not hoisted.
  • Use method shorthand, not arrows, for object methods that use this.

Further reading