Anonymous Functions
Use arrow function notation for anonymous functions e.g. when passing an inline callback. It creates a version of the function that executes in the context of this which is usually the desired functionality, and is a more concise syntax.
When dealing with a fairly complicated function, it is recommended to move that logic out into its own named function expression.
ESLint: prefer-arrow-callback and arrow-spacing
Examples
⇣ Incorrect code for this rule:
[1, 2, 3].map(function(number) {
const nextNumber = number + 1;
return number * nextNumber;
});
⇡ Correct code for this rule:
[1, 2, 3].map(number => {
const nextNumber = number + 1;
return number * nextNumber;
});
Implicit Return
If the function body consists of a single statement returning an expression without side effects, omit the braces and use the implicit return. Otherwise use a return
statement. This rule is syntactic sugar and significantly increases the readability when multiple functions are chained together.
ESLint: arrow-parens and arrow-body-style
Examples
⇣ Incorrect code for this rule:
["snow", "frost"].map(element => {
const nextElement = element;
`The winter season has ${nextElement}.`;
});
let isFalling = false;
snow(() => isFalling = true);
[1, 2, 3].map(number => {
const nextNumber = number + 1;
`A string containing the ${nextNumber}.`;
});
⇡ Correct code for this rule:
["snow", "frost"].map(element => `The winter season has ${element}.`);
["snow", "frost"].map(element => {
const sparklingElement = `sparkling ${element}`;
return `The winter season has ${sparklingElement}.`;
});
["snow", "frost"].map((element, index) => ({
[index]: element
}));
[1, 2, 3].map(number => `A string containing the ${number + 1}.`);
// No implicit return with side effects.
function seasons(callback) {
const season = callback();
if (season === "snow") {
// ...
}
}
let isFalling = false;
snow(() => {
isFalling = true;
});
Parentheses Wrap
In case the expression spans over multiple lines, wrap it in parentheses for better readability. This shows clearly where the function starts and ends.
Examples
⇣ Incorrect code for this rule:
["snow", "frost", "ice"].map(element => Object.prototype.hasOwnProperty.call(
elementObjectWithAVeryLongName,
element
)
);
⇡ Correct code for this rule:
["snow", "frost", "ice"].map(element => (
Object.prototype.hasOwnProperty.call(
elementObjectWithAVeryLongName,
element
)
));
Single Argument Parentheses
If a function takes a single argument and doesn't use braces, omit the parentheses. Otherwise, always include parentheses around arguments for clarity and consistency.
ESLint: arrow-parens
Examples
⇣ Incorrect code for this rule:
["snow", "frost"].map((element) => `sparkling ${element}`);
["snow", "frost"].map((element) => {
const sparkling = "sparkling";
return `${sparkling} ${element}`;
});
⇡ Correct code for this rule:
["snow", "frost"].map(element => `sparkling ${element}`);
["snow", "frost"].map(
element =>
`A long string about the winter season with sparkling ${element}. It's so long that we don't want it to take up space on the ".map()" line!`
);
Comparison Operators Confusion
Avoid confusing arrow function syntax =>
with comparison operators (<=
, >=
).
ESLint: no-confusing-arrow
Examples
⇣ Incorrect code for this rule:
const elementDensity = element => element.density > 256 ? element.highDensity : element.lowDensity;
const elementDensity = (element) => element.density > 256 ? element.highDensity : element.lowDensity;
⇡ Correct code for this rule:
const elementDensity = element => (element.density > 256 ? element.highDensity : element.lowDensity);
const elementDensity = element => {
const { density, highDensity, lowDensity } = element;
return density > 256 ? highDensity : lowDensity;
};