Skip to main content

Arrow functions

Arrow functions provide a concise syntax and lexically bind this. The Airbnb style guide encourages using them for inline callbacks and anonymous functions, but has specific rules about formatting.

8.1 Use arrow functions for anonymous callbacks

When you must use an anonymous function (as when passing an inline callback), use arrow function notation. eslint: prefer-arrow-callback, arrow-spacing
Arrow functions create a version of the function that executes in the context of this, which is usually what you want, and provide a more concise syntax.
Why not? If you have a fairly complicated function, you might move that logic out into its own named function expression.
[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});

8.2 Use implicit returns for single-expression bodies

If the function body consists of a single statement returning an expression without side effects, omit the braces and use the implicit return. Otherwise, keep the braces and use a return statement. eslint: arrow-parens, arrow-body-style
Syntactic sugar. It reads well when multiple functions are chained together.
// bad
[1, 2, 3].map((number) => {
  const nextNumber = number + 1;
  `A string containing the ${nextNumber}.`;
});

// good
[1, 2, 3].map((number) => `A string containing the ${number + 1}.`);

// good
[1, 2, 3].map((number) => {
  const nextNumber = number + 1;
  return `A string containing the ${nextNumber}.`;
});

// good
[1, 2, 3].map((number, index) => ({
  [index]: number,
}));

// No implicit return with side effects
function foo(callback) {
  const val = callback();
  if (val === true) {
    // Do something if callback returns true
  }
}

let bool = false;

// bad
foo(() => bool = true);

// good
foo(() => {
  bool = true;
});
Do not use implicit returns for functions with side effects. A function body that assigns to an external variable should always use explicit braces and a return statement (or no return, if none is needed).

8.3 Wrap multiline expressions in parentheses

In case the expression spans over multiple lines, wrap it in parentheses for better readability.
Parentheses show clearly where the function starts and ends.
['get', 'post', 'put'].map((httpMethod) => (
  Object.prototype.hasOwnProperty.call(
    httpMagicObjectWithAVeryLongName,
    httpMethod,
  )
));

8.4 Always include parentheses around arguments

Always include parentheses around arguments for clarity and consistency. eslint: arrow-parens
Parentheses around arguments minimize diff churn when adding or removing arguments.
[1, 2, 3].map((x) => x * x);

[1, 2, 3].map((number) => (
  `A long string with the ${number}. It's so long that we don't want it to take up space on the .map line!`
));

[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});

8.5 Avoid confusing arrow syntax with comparison operators

Avoid confusing arrow function syntax (=>) with comparison operators (<=, >=). eslint: no-confusing-arrow
When an arrow function contains <= or >=, readers can easily misread the => as a comparison operator. Use parentheses or braces to make the intent unambiguous.
// bad
const itemHeight = (item) => item.height <= 256 ? item.largeSize : item.smallSize;

// bad
const itemHeight = (item) => item.height >= 256 ? item.largeSize : item.smallSize;

// good
const itemHeight = (item) => (item.height <= 256 ? item.largeSize : item.smallSize);

// good
const itemHeight = (item) => {
  const { height, largeSize, smallSize } = item;
  return height <= 256 ? largeSize : smallSize;
};

8.6 Keep implicit return bodies on the same line

Enforce the location of arrow function bodies with implicit returns. eslint: implicit-arrow-linebreak
(foo) => bar;
(foo) => (bar);
(foo) => (
   bar
)
When the implicit return value is short, keep it on the same line as the arrow. For longer expressions, wrap in parentheses and continue on the next line — but the opening parenthesis must stay on the arrow line.

Build docs developers (and LLMs) love