Arrow Functions

  • 8.1 When you must use an anonymous function (as when passing an inline callback), use arrow function notation. eslint: prefer-arrow-callback, arrow-spacing

    Why? It creates a version of the function that executes in the context of this, which is usually what you want, and is 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. // bad
    2. [1, 2, 3].map(function (x) {
    3. const y = x + 1;
    4. return x * y;
    5. });
    6. // good
    7. [1, 2, 3].map((x) => {
    8. const y = x + 1;
    9. return x * y;
    10. });

  • 8.2 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

    Why? Syntactic sugar. It reads well when multiple functions are chained together.

    ``javascript // 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}.);

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

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

  1. [index]: number,
  2. }));
  3. // No implicit return with side effects
  4. function foo(callback) {
  5. const val = callback();
  6. if (val === true) {
  7. // Do something if callback returns true
  8. }
  9. }
  10. let bool = false;
  11. // bad
  12. foo(() => bool = true);
  13. // good
  14. foo(() => {
  15. bool = true;
  16. });
  17. ```

  • 8.3 In case the expression spans over multiple lines, wrap it in parentheses for better readability.

    Why? It shows clearly where the function starts and ends.

    1. // bad
    2. ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
    3. httpMagicObjectWithAVeryLongName,
    4. httpMethod,
    5. )
    6. );
    7. // good
    8. ['get', 'post', 'put'].map(httpMethod => (
    9. Object.prototype.hasOwnProperty.call(
    10. httpMagicObjectWithAVeryLongName,
    11. httpMethod,
    12. )
    13. ));

  • 8.4 If your function takes a single argument and doesn’t use braces, omit the parentheses. Otherwise, always include parentheses around arguments for clarity and consistency. Note: it is also acceptable to always use parentheses, in which case use the “always” option for eslint. eslint: arrow-parens

    Why? Less visual clutter.

    1. // bad
    2. [1, 2, 3].map((x) => x * x);
    3. // good
    4. [1, 2, 3].map(x => x * x);
    5. // good
    6. [1, 2, 3].map(number => (
    7. `A long string with the ${number}. Its so long that we dont want it to take up space on the .map line!`
    8. ));
    9. // bad
    10. [1, 2, 3].map(x => {
    11. const y = x + 1;
    12. return x * y;
    13. });
    14. // good
    15. [1, 2, 3].map((x) => {
    16. const y = x + 1;
    17. return x * y;
    18. });

  • 8.5 Avoid confusing arrow function syntax (=>) with comparison operators (<=, >=). eslint: no-confusing-arrow

    1. // bad
    2. const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
    3. // bad
    4. const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
    5. // good
    6. const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
    7. // good
    8. const itemHeight = (item) => {
    9. const { height, largeSize, smallSize } = item;
    10. return height > 256 ? largeSize : smallSize;
    11. };

  • 8.6 Enforce the location of arrow function bodies with implicit returns. eslint: implicit-arrow-linebreak

    1. // bad
    2. (foo) =>
    3. bar;
    4. (foo) =>
    5. (bar);
    6. // good
    7. (foo) => bar;
    8. (foo) => (bar);
    9. (foo) => (
    10. bar
    11. )