Wrap immediately invoked function expressions in parentheses. eslint:
wrap-iife
// immediately-invoked function expression (IIFE)
(function () {
console.log('Welcome to the Internet. Please follow me.');
}());
Never declare a function in a non-function block (
if
,while
, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears. eslint:no-loop-func
Note: ECMA-262 defines a
block
as a list of statements. A function declaration is not a statement.// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
let test;
if (currentUser) {
test = () => {
console.log('Yup.');
};
}
7.5 Never name a parameter
arguments
. This will take precedence over thearguments
object that is given to every function scope.// bad
function foo(name, options, arguments) {
// ...
}
// good
function foo(name, options, args) {
// ...
}
-
Why?
...
is explicit about which arguments you want pulled. Plus, rest arguments are a real Array, and not merely Array-like likearguments
. Use default parameter syntax rather than mutating function arguments.
// really bad
function handleThings(opts) {
// No! We shouldn’t mutate function arguments.
// Double bad: if opts is falsy it'll be set to an object which may
// be what you want but it can introduce subtle bugs.
opts = opts || {};
// ...
}
// still bad
function handleThings(opts) {
opts = {};
}
}
// good
function handleThings(opts = {}) {
// ...
}
7.8 Avoid side effects with default parameters.
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
Always put default parameters last.
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
7.10 Never use the Function constructor to create a new function. eslint:
Why? Creating a function in this way evaluates a string similarly to
eval()
, which opens vulnerabilities.-
// bad
const f = function(){};
const g = function (){};
const h = function() {};
// good
const x = function () {};
const y = function a() {};
7.12 Never mutate parameters. eslint:
Why? Manipulating objects passed in as parameters can cause unwanted variable side effects in the original caller.
// bad
function f1(obj) {
obj.key = 1;
}
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
}
7.13 Never reassign parameters. eslint:
function f1(a) {
a = 1;
// ...
}
function f2(a) {
if (!a) { a = 1; }
// ...
}
// good
function f3(a) {
const b = a || 1;
// ...
}
function f4(a = 1) {
// ...
}
7.14 Prefer the use of the spread operator
...
to call variadic functions. eslint:Why? It’s cleaner, you don’t need to supply a context, and you can not easily compose
new
withapply
.Functions with multiline signatures, or invocations, should be indented just like every other multiline list in this guide: with each item on a line by itself, with a trailing comma on the last item. eslint:
function-paren-newline
// bad
function foo(bar,
baz,
quux) {
// ...
}
// good
function foo(
bar,
baz,
quux,
) {
// ...
}
// bad
console.log(foo,
bar,
baz);
// good
console.log(
foo,
bar,