#JS 编码最佳实践
强制数组方法的回调函数中有 return 语句,该规则只检查需要有返回值的那些方法,包括 form、 every、 filter、 find、 findIndex、 map、 reduce、 reduceRight、 some、 sort
"array-callback-return": 1
不推荐的做法:
var indexMap = myArray.reduce(function(memo, item, index) {
memo[item] = index;
}, {});
var foo = Array.from(nodes, function(node) {
if (node.tagName === "DIV") {
return true;
}
});
var bar = foo.filter(function(x) {
if (x) {
return true;
} else {
return;
}
});
好的做法:
var indexMap = myArray.reduce(function(memo, item, index) {
memo[item] = index;
return memo;
}, {});
var foo = Array.from(nodes, function(node) {
if (node.tagName === "DIV") {
return true;
}
return false;
});
var bar = foo.map(node => node.getAttribute("id"));
强制把变量的使用限制在其定义的作用域范围内
"block-scoped-var": 1
不推荐的做法:
function doIf() {
if (true) {
var build = true;
}
console.log(build);
}
function doIfElse() {
if (true) {
var build = true;
} else {
var build = false;
}
}
function doTryCatch() {
try {
var build = 1;
} catch (e) {
var f = build;
}
}
好的做法:
function doIf() {
var build;
if (true) {
build = true;
}
console.log(build);
}
function doIfElse() {
var build;
if (true) {
build = true;
} else {
build = false;
}
}
function doTryCatch() {
var build;
var f;
try {
build = 1;
} catch (e) {
f = build;
}
}
指定程序中允许的最大环路复杂度(即 if else 的个数),默认20
"complexity": 2
示例:
// 像这样,很多个 if、 else if、 else 不便于维护
// 所以需要限制一下个数
if (true) {
return x;
} else if (false) {
return x+1;
} else {
return 4; // 3rd path
}
要求 return 语句要么总是指定返回的值,要么不指定
"consistent-return": 1
示例:
// BAD
function doSomething(condition) {
if (condition) {
return true;
} else {
return;
}
}
// GOOD
function doSomething(condition) {
if (condition) {
return true;
} else {
return false;
}
}
要求 switch 语句中有 default 分支,即便 default 什么也不做
"default-case": 1
要求点操作符和属性放在同一行
"dot-location": [1, "property"]
示例:
// BAD
var foo = object.
property;
// GOOD
var foo = object
.property;
var bar = object.property;
强制尽可能地使用点号读取对象属性
"dot-notation": 1
示例:
// BAD
var x = foo["bar"];
// GOOD
var x = foo.bar;
// 属性名是保留字,需要方括号表示法
var x = foo[bar];
强制每个文件中包含的的类的最大数量为 1,一个文件只允许声明一个类
"max-classes-per-file": [1, 1]
禁止使用 alert、confirm 和 prompt
"no-alert": 2
禁止使用 arguments.caller 或 arguments.callee
"no-caller": 1
不允许在 case 子句中声明变量
"no-case-declarations": 2
不推荐的做法:
switch (foo) {
case 1:
let x = 1;
break;
case 2:
const y = 2;
break;
case 3:
function f() {}
break;
default:
class C {}
}
禁止使用看起来像除法的正则表达式
"no-div-regex": 1
示例:
// BAD
function bar() { return /=foo/; }
// GOOD
function bar() { return /[=]foo/; }
禁止 if 语句中 return 语句之后有 else 块
"no-else-return": 1
禁止出现空函数
"no-empty-function": 1
不推荐的做法:
function foo() {}
var foo = function() {};
var foo = () => {};
function* foo() {}
var foo = function*() {};
禁止使用空解构模式
"no-empty-pattern": 1
不推荐的做法:
var {} = foo;
var [] = foo;
var {a: {}} = foo;
var {a: []} = foo;
function foo({}) {}
function foo([]) {}
function foo({a: {}}) {}
function foo({a: []}) {}
禁止在没有类型检查操作符的情况下与 null 进行比较
"no-eq-null": 1
示例:
// BAD
if (foo == null) {
bar();
}
while (qux != null) {
baz();
}
// GOOD
if (foo === null) {
bar();
}
while (qux !== null) {
baz();
}
禁用 eval() ,因为它可能产生非常多的变数
"no-eval": 2
禁止扩展原生类型
"no-extend-native": 2
不推荐的做法:
Object.prototype.a = "a";
Object.defineProperty(Array.prototype, "times", { value: 999 });
禁止不必要的 .bind() 调用
"no-extra-bind": 1
不推荐的做法:
var x = function () {
foo();
}.bind(bar);
var x = (() => {
foo();
}).bind(bar);
var x = (() => {
this.foo();
}).bind(bar);
var x = function () {
(function () {
this.foo();
}());
}.bind(bar);
var x = function () {
function foo() {
this.bar();
}
}.bind(baz);
好的做法:
var x = function () {
this.foo();
}.bind(bar);
var x = function (a) {
return a + 1;
}.bind(foo, bar);
禁用不必要的标签
"no-extra-label": 1
不推荐的做法:
A: while (a) {
break A;
}
B: for (let i = 0; i < 10; ++i) {
break B;
}
C: switch (a) {
case 0:
break C;
}
好的做法:
while (a) {
break;
}
for (let i = 0; i < 10; ++i) {
break;
}
switch (a) {
case 0:
break;
}
A: {
break A;
}
B: while (a) {
while (b) {
break B;
}
}
C: switch (a) {
case 0:
while (b) {
break C;
}
break;
}
禁止 case 语句落空
"no-fallthrough": 1
不推荐的做法:
switch(foo) {
case 1:
doSomething();
case 2:
doSomething();
}
好的做法:
switch(foo) {
case 1:
doSomething();
break;
case 2:
doSomething();
}
function bar(foo) {
switch(foo) {
case 1:
doSomething();
return;
case 2:
doSomething();
}
}
禁止数字字面量中使用前导和末尾小数点
"no-floating-decimal": 1
不推荐的做法:
var num = .5;
var num = 2.;
var num = -.7;
好的做法:
var num = 0.5;
var num = 2.0;
var num = -0.7;
禁止对原生对象或只读的全局对象进行赋值
"no-global-assign": 2
不推荐的做法:
Object = null
undefined = 1
禁止使用短符号进行类型转换
"no-implicit-coercion": [1, { // 禁止使用短符号进行类型转换
"boolean": false // 布尔值除外
}]
不推荐的做法:
var b = !!foo;
var b = ~foo.indexOf(".");
var n = +foo;
var n = 1 * foo;
var s = "" + foo;
foo += ``;
好的做法:
var b = Boolean(foo);
var b = foo.indexOf(".") !== -1;
var n = Number(foo);
var n = Number(foo);
var s = String(foo);
foo = String(foo);
禁止在全局范围内使用变量声明和 function 声明
"no-implicit-globals": 1
不推荐的做法:
var foo = 1;
function bar() {}
好的做法:
window.foo = 1;
window.bar = function() {};
// intended to be scope to this file
(function() {
var foo = 1;
function bar() {}
})();
禁止使用类似 eval() 的方法
"no-implied-eval": 2
不推荐的做法:
setTimeout("alert('Hi!');", 100);
setInterval("alert('Hi!');", 100);
execScript("alert('Hi!')");
window.setTimeout("count = 5", 10);
window.setInterval("foo = bar", 10);
好的做法:
setTimeout(function() {
alert("Hi!");
}, 100);
setInterval(function() {
alert("Hi!");
}, 100);
禁止 this 关键字出现在类和类对象之外
"no-invalid-this": 2
描述略微复杂,自行查看文档
禁用 __iterator__ 属性
"no-iterator": 1
不推荐的做法:
Foo.prototype.__iterator__ = function() {
return new FooIterator(this);
};
foo.__iterator__ = function () {};
foo["__iterator__"] = function () {};
禁用不必要的嵌套块
"no-lone-blocks": 1
不推荐的做法:
if (foo) {
bar();
{
baz();
}
}
function bar() {
{
baz();
}
}
禁止在循环语句中出现包含不安全引用的函数声明
"no-loop-func": 1
不推荐的做法:
for (var i=10; i; i--) {
(function() { return i; })();
}
while(i) {
var a = function() { return i; };
a();
}
do {
function a() { return i; };
a();
} while (i);
let foo = 0;
for (let i = 0; i < 10; ++i) {
//Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
setTimeout(() => console.log(foo));
foo += 1;
}
for (let i = 0; i < 10; ++i) {
//Bad, `foo` is not in the loop-block's scope and `foo` is modified in/after the loop
setTimeout(() => console.log(foo));
}
foo = 100;
禁用魔术数字
魔术数字是在代码中多次出现的没有明确含义的数字。它最好由命名常量取代。
"no-magic-numbers": 2
禁止使用多个空格
"no-multi-spaces": 1
不推荐的做法:
var a = 1;
if(foo === "bar") {}
a << b
var arr = [1, 2];
a ? b: c
好的做法:
var a = 1;
if(foo === "bar") {}
a << b
var arr = [1, 2];
a ? b: c
禁止使用多行字符串
"no-multi-str": 1
示例:
// BAD
var x = "Line 1 \
Line 2";
// GOOD
var x = "Line 1\n" +
"Line 2";
禁止对 Function 对象使用 new 操作符
"no-new-func": 1
示例:
// BAD
var x = new Function("a", "b", "return a + b");
var x = Function("a", "b", "return a + b");
// GOOD
var x = function (a, b) {
return a + b;
};
禁止对 String,Number 和 Boolean 使用 new 操作符
"no-new-wrappers": 1
示例:
// BAD
var stringObject = new String("Hello world");
var numberObject = new Number(33);
var booleanObject = new Boolean(false);
var stringObject = new String;
var numberObject = new Number;
var booleanObject = new Boolean;
// GOOD
var text = String(someValue);
var num = Number(someValue);
var object = new MyString();
禁用八进制字面量
"no-octal": 1
示例:
// BAD
var num = 071;
var result = 5 + 07;
// GOOD
var num = "071";
禁止在字符串中使用八进制转义序列
"no-octal-escape": 1
示例:
// BAD
`var foo = "Copyright \251";`
// GOOD
var foo = "Copyright \u00A9"; // unicode
var foo = "Copyright \xA9"; // hexadecimal
禁止对 function 的参数进行重新赋值
"no-param-reassign": 1
不推荐的做法:
function foo(bar) {
bar = 13;
}
function foo(bar) {
bar++;
}
禁用 __proto__ 属性
"no-proto": 1
不推荐的做法:
var a = obj.__proto__;
var a = obj["__proto__"];
obj.__proto__ = b;
obj["__proto__"] = b;
好的做法:
var a = Object.getPrototypeOf(obj);
Object.setPrototypeOf(obj, b);
var c = { __proto__: a };
禁止多次声明同一变量
"no-redeclare": 2
禁止在 return 语句中使用赋值语句
"no-return-assign": 1
不推荐的做法:
function doSomething() {
return foo = bar + 2;
}
function doSomething() {
return foo += 2;
}
禁用不必要的 return await
"no-return-await": 1
示例:
// BAD
async function foo() {
return await bar();
}
// GOOD
async function foo() {
return bar();
}
async function foo() {
await bar();
return;
}
async function foo() {
const x = await bar();
return x;
}
async function foo() {
try {
return await bar();
} catch (error) {}
}
禁止使用 javascript: url
"no-script-url": 2
不推荐的做法:
location.href = "javascript:void(0)";
禁止自我赋值
"no-self-assign": 2
不推荐的做法:
foo = foo;
[a, b] = [a, b];
[a, ...b] = [x, ...b];
({a, b} = {a, x});
禁止自身比较
"no-self-compare": 2
不推荐的做法:
var x = 10;
if (x === x) {
x = 20;
}
禁用逗号操作符
"no-sequences": 2
描述比较复杂,自行看文档
禁止抛出异常字面量
"no-throw-literal": 2
不推荐的做法:
throw "error";
throw 0;
throw undefined;
throw null;
var err = new Error();
throw "an " + err;
// err is recast to a string literal
var err = new Error();
throw `${err}`
好的做法:
throw new Error();
throw new Error("error");
var e = new Error("error");
throw e;
try {
throw new Error("error");
} catch (e) {
throw e;
}
禁用一成不变的循环条件
"no-unmodified-loop-condition": 2
不推荐的做法:
while (node) {
doSomething(node);
}
node = other;
for (var j = 0; j < items.length; ++i) {
doSomething(items[j]);
}
while (node !== root) {
doSomething(node);
}
好的做法:
while (node) {
doSomething(node);
node = node.parent;
}
for (var j = 0; j < items.length; ++j) {
doSomething(items[j]);
}
// OK, the result of this binary expression is changed in this loop.
while (node !== root) {
doSomething(node);
node = node.parent;
}
// OK, the result of this ternary expression is changed in this loop.
while (node ? A : B) {
doSomething(node);
node = node.parent;
}
// A property might be a getter which has side effect...
// Or "doSomething" can modify "obj.foo".
while (obj.foo) {
doSomething(obj);
}
// A function call can return various values.
while (check(obj)) {
doSomething(obj);
}
禁止出现未使用过的表达式
"no-unused-expressions": 2
规则极其复杂,大致是说不要写一些奇奇怪怪没有意义的代码,具体自己看文档
禁用出现未使用过的标签
"no-unused-labels": 2
不推荐的做法:
A: var foo = 0;
B: {
foo();
}
C:
for (let i = 0; i < 10; ++i) {
foo();
}
禁止不必要的 .call() 和 .apply()
"no-useless-call": 2
不推荐的做法:
foo.call(undefined, 1, 2, 3);
foo.apply(undefined, [1, 2, 3]);
foo.call(null, 1, 2, 3);
foo.apply(null, [1, 2, 3]);
// These are same as `obj.foo(1, 2, 3);`
obj.foo.call(obj, 1, 2, 3);
obj.foo.apply(obj, [1, 2, 3]);
好的做法:
// The `this` binding is different.
foo.call(obj, 1, 2, 3);
foo.apply(obj, [1, 2, 3]);
obj.foo.call(null, 1, 2, 3);
obj.foo.apply(null, [1, 2, 3]);
obj.foo.call(otherObj, 1, 2, 3);
obj.foo.apply(otherObj, [1, 2, 3]);
// The argument list is variadic.
// Those are warned by the `prefer-spread` rule.
foo.apply(undefined, args);
foo.apply(null, args);
obj.foo.apply(obj, args);
禁止不必要的 catch 子句
"no-useless-catch": 2
不推荐的做法:
try {
doSomethingThatMightThrow();
} catch (e) {
throw e;
}
try {
doSomethingThatMightThrow();
} catch (e) {
throw e;
} finally {
cleanUp();
}
好的做法:
try {
doSomethingThatMightThrow();
} catch (e) {
doSomethingBeforeRethrow();
throw e;
}
try {
doSomethingThatMightThrow();
} catch (e) {
handleError(e);
}
禁止不必要的字符串字面量或模板字面量的连接
"no-useless-concat": 2
不推荐的做法:
var a = `some` + `string`;
// these are the same as "10"
var a = '1' + '0';
var a = '1' + `0`;
var a = `1` + '0';
var a = `1` + `0`;
禁用不必要的转义字符
"no-useless-escape": 2
不推荐的做法:
"\'";
'\"';
"\#";
"\e";
`\"`;
`\"${foo}\"`;
`\#{foo}`;
/\!/;
/\@/;
好的做法:
"\"";
'\'';
"\x12";
"\u00a9";
"\371";
"xs\u2111";
`\``;
`\${${foo}}`;
`$\{${foo}}`;
/\\/g;
/\t/g;
/\w\$\*\^\./;
禁止多余的 return 语句
"no-useless-return": 1
不推荐的做法:
function foo() { return; }
function foo() {
doSomething();
return;
}
function foo() {
if (condition) {
bar();
return;
} else {
baz();
}
}
function foo() {
switch (bar) {
case 1:
doSomething();
default:
doSomethingElse();
return;
}
}
好的做法:
function foo() { return 5; }
function foo() {
return doSomething();
}
function foo() {
if (condition) {
bar();
return;
} else {
baz();
}
qux();
}
function foo() {
switch (bar) {
case 1:
doSomething();
return;
default:
doSomethingElse();
}
}
function foo() {
for (const foo of bar) {
return;
}
}
禁用 void 操作符
"no-void": 2
不推荐的做法:
void foo
var foo = void bar();
禁用 with 语句
"no-with": 2
禁止使用不带 await 表达式的 async 函数
"require-await": 1
不推荐的做法:
async function foo() {
doSomething();
}
bar(async () => {
doSomething();
});
好的做法:
async function foo() {
await doSomething();
}
bar(async () => {
await doSomething();
});
function foo() {
doSomething();
}
bar(() => {
doSomething();
});
// Allow empty functions.
async function noop() {}
要求 IIFE 使用括号括起来
"wrap-iife": 1
示例:
// BAD
var x = function () { return { y: 1 };}(); // unwrapped
var x = (function () { return { y: 1 };})(); // wrapped function expression
// GOOD
var x = (function () { return { y: 1 };}()); // wrapped call expression