Declaration
Use named function expressions instead of function declarations. Function declarations are hoisted, which means that it is (too) easy to reference the function before it is defined in the file. This harms readability and maintainability.
Functions which definition is too large or complex should be extracted into a own module. Make sure to explicitly name the expression, regardless of whether or not the name is inferred from the containing variable which is often the case in modern browsers or when using compilers such as Babel. This eliminates any assumptions made about the call stack of errors.
ESLint: func-style
Examples
⇣ Incorrect code for this rule:
function winter() {
// ...
}
const winter = function() {
// ...
};
⇡ Correct code for this rule:
// Lexical name distinguished from the variable-referenced invocation(s).
const winter = function longUniqueMoreDescriptiveLexicalWinter() {
// ...
};
IIFE
Wrap immediately invoked function expressions (IIFE) in parentheses. An immediately invoked function expression is a single unit - wrapping both it, and its invocation parens, in parens, cleanly expresses this. Note that in a world with modules everywhere, an IIFE is almost never needed.
ESLint: wrap-iife
Examples
⇡ Correct code for this rule:
(function() {
console.log("The winter is snowy and sparkling.");
})();
Block Declaration
Never declare a function in a non-function block (if
, while
, etc). Assign the function to a variable instead. Most browsers will allow it, but they all interpret it differently.
Note: ECMA-262 defines a block as a list of statements. A function declaration is not a statement!
ESLint: no-loop-func
Examples
⇣ Incorrect code for this rule:
if (winter) {
function snow() {
console.log("Snowy!");
}
}
⇡ Correct code for this rule:
let snow;
if (winter) {
snow = () => {
console.log("Snowy!");
};
}
Prevent arguments
Shadow
Never name a parameter arguments
! This will take precedence over the arguments
object that is given to every function scope.
Examples
⇣ Incorrect code for this rule:
function season(name, elements, arguments) {
// ...
}
⇡ Correct code for this rule:
function season(name, elements, args) {
// ...
}
ES6 Rest
Never use arguments
and use rest syntax ...
instead. The rest ...
operator is explicit about which arguments to pull. Also rest arguments are a real Array, and not merely Array-like like arguments
.
ESLint: prefer-rest-params
Examples
⇣ Incorrect code for this rule:
function concatenateSeasons() {
const seasons = Array.prototype.slice.call(arguments);
return seasons.join("");
}
⇡ Correct code for this rule:
function concatenateSeasons(...seasons) {
return seasons.join("");
}
ES6 Default Parameters
Use default parameter syntax rather than mutating function arguments.
Examples
↯ Critical incorrect code for this rule:
function winter(elements) {
/*
* This mutates function arguments!
* If "elements" is falsy it'll also be set to an object which can introduce subtle bugs.
*/
elements = elements || {};
// ...
}
⇣ Incorrect code for this rule:
function winter(elements) {
if (elements === void 0) {
elements = {};
}
// ...
}
⇡ Correct code for this rule:
function winter(elements = {}) {
// ...
}
Default Side Effects
Avoid side effects with default parameters.
Examples
⇣ Incorrect code for this rule:
let snowflakes = 1;
function count(amount = snowflakes++) {
console.log(amount);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
Default Parameter Ordering
Always put default parameters last.
Examples
⇣ Incorrect code for this rule:
function winter(elements = {}, name) {
// ...
}
⇡ Correct code for this rule:
function winter(name, elements = {}) {
// ...
}
Constructor
Never use the Function
constructor to create a new function. Creating a function in this way evaluates a string similarly to eval()
, which opens vulnerabilities.
ESLint: no-new-func
Examples
⇣ Incorrect code for this rule:
const add = new Function("snow", "frost", "return snow + frost");
const subtract = Function("snow", "frost", "return snow - frost");
Signature Spacing
Use spacing in a function signature for named functions while anonymous functions must not contain a space between the parentheses and the function
keyword.
ESLint: space-before-function-paren and space-before-blocks
Examples
⇣ Incorrect code for this rule:
const snow = function(){};
const snow = function (){};
⇡ Correct code for this rule:
const snow = function() {};
const snow = function flake() {};
Parameter Mutation
Never mutate parameters. Manipulating objects passed in as parameters can cause unwanted variable side effects in the original caller.
ESLint: no-param-reassign
Examples
⇣ Incorrect code for this rule:
function snow(flake) {
flake.key = 1;
}
⇡ Correct code for this rule:
function snow(flake) {
const key = Object.prototype.hasOwnProperty.call(flake, "key") ? flake.key : 1;
}
Parameter Reassign
Never reassign parameters. It can lead to unexpected behavior, especially when accessing the arguments
object. It can also cause optimization issues, especially in V8.
ESLint: no-param-reassign
Examples
⇣ Incorrect code for this rule:
function snow(flake) {
flake = 1;
// ...
}
function snow(flake) {
if (!flake) {
flake = 1;
}
// ...
}
⇡ Correct code for this rule:
function snow(flake) {
const flakeCopy = flake || 1;
// ...
}
function snow(flake = 1) {
// ...
}
ES6 Spread
Use of the spread operator ...
to call variadic functions. It's cleaner, avoids the supply of a context and also prevents the compose of new
with apply
.
ESLint: prefer-spread
Examples
⇣ Incorrect code for this rule:
const winter = ["snow", "frost"];
console.log.apply(console, winter);
new (Function.prototype.bind.apply(Date, [null, 2018, 1, 20]));
⇡ Correct code for this rule:
const winter = ["snow", "frost"];
console.log(...winter);
new Date(...[2018, 1, 20]);
Signature Invocation Indentation
Functions with multiline signatures, or invocations, should be indented like every other multiline list. Each item on a line by itself.
ESLint: function-paren-newline
Examples
⇣ Incorrect code for this rule:
function winter(snow,
frost,
ice) {
// ...
}
console.log(snow,
frost,
ice);
⇡ Correct code for this rule:
function winter(
snow,
frost,
ice
) {
// ...
}
console.log(
snow,
frost,
ice
);