#JS 代码规范
必须遵守的规则
强制 “for” 循环中更新子句的计数器朝着正确的方向移动
"for-direction": 2
错误示范:
for (var i = 0; i < 10; i--) {
}
for (var i = 10; i >= 0; i++) {
}
禁止使用异步函数作为 Promise executor
"no-async-promise-executor": 2
错误示范:
const result = new Promise(async (resolve, reject) => {
resolve(await foo);
});
禁止在循环中出现 await
"no-await-in-loop": 2
错误示范:
async function foo(things) {
const results = [];
for (const thing of things) {
// Bad: each loop iteration is delayed until the entire asynchronous operation completes
results.push(await bar(thing));
}
return baz(results);
}
禁止与 -0 进行比较
"no-compare-neg-zero": 2
错误示范:
if (x === -0) {
// doSomething()...
}
禁止条件表达式中出现赋值操作符
"no-cond-assign": 2
错误示范:
if (x = 0) {
var b = 1;
}
禁止在条件中使用常量表达式
"no-constant-condition": 2
错误示范:
if (false) {
doSomethingUnfinished();
}
if (void x) {
doSomethingUnfinished();
}
for (;-2;) {
doSomethingForever();
}
while (typeof x) {
doSomethingForever();
}
do {
doSomethingForever();
} while (x = -1);
var result = 0 ? a : b;
禁止在正则表达式中使用控制字符
"no-control-regex": 2
错误示范:
var pattern1 = /\x1f/;
var pattern2 = new RegExp("\x1f");
禁用 debugger
,因为现在这个已经不是最佳调试方式
"no-debugger": 2
禁止 function 定义中出现重名参数
"no-dupe-args": 2
错误示范:
function foo(a, b, a) {
console.log("value of the second a:", a);
}
var bar = function (a, b, a) {
console.log("value of the second a:", a);
};
禁止对象字面量中出现重复的 key
"no-dupe-keys": 2
错误示范:
var foo = {
bar: "baz",
bar: "qux"
};
var foo = {
"bar": "baz",
bar: "qux"
};
var foo = {
0x1: "baz",
1: "qux"
};
禁止出现重复的 case 标签
"no-duplicate-case": 2
错误示范:
switch (a) {
case 1:
break;
case 2:
break;
case 1: // duplicate test expression
break;
default:
break;
}
禁止出现空语句块
"no-empty": 2
错误示范:
if (foo) {
}
while (foo) {
}
switch(foo) {
}
try {
doSomething();
} catch(ex) {
} finally {
}
禁止在正则表达式中使用空字符集
"no-empty-character-class": 2
错误示范:
/^abc[]/.test("abcdefg"); // false
"abcdefg".match(/^abc[]/); // null
禁止对 catch 子句的参数重新赋值
"no-ex-assign": 2
错误示范:
try {
// code
} catch (e) {
e = 10;
}
禁止不必要的布尔转换
"no-extra-boolean-cast": 1
错误示范:
var foo = !!!bar;
var foo = !!bar ? baz : bat;
var foo = Boolean(!!bar);
var foo = new Boolean(!!bar);
禁止不必要的括号
"no-extra-parens": 1
错误示范:
a = (b * c);
(a * b) + c;
for (a in (b, c));
for (a in (b));
for (a of (b));
typeof (a);
(function(){} ? a() : b());
禁止不必要的分号
"no-extra-semi": 1,
错误示范:
var x = 5;;
function foo() {
// code
};
禁止对 function 声明重新赋值
"no-func-assign": 2
错误示范:
function foo() {}
foo = bar;
function foo() {
foo = bar;
}
禁止在嵌套的块中出现变量声明或 function 声明
"no-inner-declarations": 2
错误示范:
// Bad
if (test) {
function doSomethingElse () { }
}
function anotherThing() {
var fn;
if (test) {
// Good
fn = function expression() { };
// Bad
function declaration() { }
}
}
禁止 RegExp 构造函数中存在无效的正则表达式字符串
"no-invalid-regexp": 2
错误示范:
RegExp('[')
RegExp('.', 'z')
new RegExp('\\')
禁止不规则的空白
"no-irregular-whitespace": 2
不允许在字符类语法中出现由多个代码点组成的字符(表情之类的奇奇怪怪的内容)
"no-misleading-character-class": 2
禁止把全局对象作为函数调用
"no-obj-calls": 2
错误示范:
var math = Math();
var json = JSON();
var reflect = Reflect();
禁止直接调用 Object.prototypes 的内置属性(这条不明白,所以没开启)
"no-prototype-builtins": 0
示例:
// BAD
var hasBarProperty = foo.hasOwnProperty("bar");
var isPrototypeOfBar = foo.isPrototypeOf(bar);
var barIsEnumerable = foo.propertyIsEnumerable("bar");
// GOOD
var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");
var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);
var barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar");
禁止正则表达式字面量中出现多个空格
"no-regex-spaces": 2
错误示范:
var re = /foo bar/;
var re = new RegExp("foo bar");
禁用稀疏数组
"no-sparse-arrays": 2
错误示范:
var items = [,];
var colors = [ "red",, "blue" ];
禁止在常规字符串中出现模板字面量占位符语法
"no-template-curly-in-string": 0
错误示范:
// 这些都是字符串,而不是字符串模板,不要写得和字符串模板一样
"Hello ${name}!";
'Hello ${name}!';
"Time: ${12 * 60 * 60 * 1000}";
禁止出现令人困惑的多行表达式
"no-unexpected-multiline": 2
示范:
// BAD 必要的分号不能省略
var foo = bar
(1 || 2).baz();
var hello = 'world'
[1, 2, 3].forEach(addNumber);
let x = function() {}
`hello`
let x = function() {}
x
`hello`
let x = foo
/regex/g.test(bar)
// GOOD
var foo = bar;
(1 || 2).baz();
var foo = bar
;(1 || 2).baz()
var hello = 'world';
[1, 2, 3].forEach(addNumber);
var hello = 'world'
void [1, 2, 3].forEach(addNumber);
let x = function() {};
`hello`
let tag = function() {}
tag `hello`
禁止在 return、throw、continue 和 break 语句之后出现不可达代码
"no-unreachable": 2
错误示范:
function foo() {
return true;
console.log("done");
}
function bar() {
throw new Error("Oops!");
console.log("done");
}
while(value) {
break;
console.log("done");
}
throw new Error("Oops!");
console.log("done");
function baz() {
if (Math.random() < 0.5) {
return;
} else {
throw new Error();
}
console.log("done");
}
for (;;) {}
console.log("done");
禁止在 finally 语句块中出现控制流语句
"no-unsafe-finally": 2
示例:
// BAD
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
return 3;
}
};
// GOOD
let foo = function() {
try {
return 1;
} catch(err) {
return 2;
} finally {
console.log("hola!");
}
};
禁止对关系运算符的左操作数使用否定操作符
"no-unsafe-negation": 2
错误示范:
if (!key in object) {
// operator precedence makes it equivalent to (!key) in object
// and type conversion makes it equivalent to (key ? "false" : "true") in object
}
if (!obj instanceof Ctor) {
// operator precedence makes it equivalent to (!obj) instanceof Ctor
// and it equivalent to always false since boolean values are not objects.
}
禁止由于 await 或 yield的使用而可能导致出现竞态条件的赋值
"require-atomic-updates": 2
错误示范:
// BAD
let result;
async function foo() {
result += await somethingElse;
result = result + await somethingElse;
result = result + doSomething(await somethingElse);
}
function* bar() {
result += yield;
result = result + (yield somethingElse);
result = result + doSomething(yield somethingElse);
}
// GOOD
let result;
async function foo() {
result = await somethingElse + result;
let tmp = await somethingElse;
result += tmp;
let localVariable = 0;
localVariable += await somethingElse;
}
function* bar() {
result += yield;
result = (yield somethingElse) + result;
result = doSomething(yield somethingElse, result);
}
要求使用 isNaN() 检查 NaN
"use-isnan": 2
示范:
// BAD
if (foo == NaN) {
// ...
}
// GOOD
if (isNaN(foo)) {
// ...
}
强制 typeof 表达式与有效的字符串进行比较
"valid-typeof": 2
示例:
// BAD
typeof foo === "strnig"
typeof foo == "undefimed"
typeof bar != "nunber"
typeof bar !== "fucntion"
// GOOD
typeof foo === "string"
typeof bar == "undefined"
typeof foo === baz
typeof bar === typeof qux
其他的规范,1 或 warn 为建议执行,2 或 error 为必须遵守
变量相关规范
要求 var 声明时赋予初始值
"init-declarations": [1, "always"]
禁止删除变量
"no-delete-var": 2,
不允许标签与变量同名
"no-label-var": 2
错误示范:
var x = foo;
function bar() {
x:for (;;) {
break x;
}
}
禁止变量声明与外层作用域的变量同名
"no-shadow": 1
错误示范:
var a = 3;
function b() {
var a = 10;
}
var b = function () {
var a = 10;
}
function b(a) {
a = 10;
}
b(a);
if (true) {
let a = 5;
}
禁止将标识符定义为受限的名字
"no-shadow-restricted-names": 2
错误示范:
function NaN(){}
!function(Infinity){};
var undefined = 5;
try {} catch(eval){}
禁用未声明的变量,除非它们在 //* global *// 注释中被提到
"no-undef": 2
错误示范:
var a = someFunction();
b = 10;
正确的做法:
/*global someFunction b:true*/
/*eslint no-undef: "error"*/
var a = someFunction();
b = 10;
禁止将变量初始化为 undefined
"no-undef-init": 2
错误示范:
var foo = undefined;
let bar = undefined;
禁止将 undefined 作为标识符
"no-undefined": 2
禁止出现未使用过的变量
"no-unused-vars": 1
禁止在变量定义之前使用它们
"no-use-before-define": 2
Node.js and CommonJS
要求 require() 出现在顶层模块作用域中
"global-require": 1
错误示例:
function readFile(filename, callback) {
var fs = require('fs');
fs.readFile(filename, callback)
}
// conditional requires like this are also not allowed
if (DEBUG) { require('debug'); }
// a require() in a switch statement is also flagged
switch(x) { case '1': require('1'); break; }
// you may not require() inside an arrow function body
var getModule = (name) => require(name);
// you may not require() inside of a function body as well
function getModule(name) { return require(name); }
// you may not require() inside of a try/catch block
try {
require(unsafeModule);
} catch(e) {
console.log(e);
}
好的做法:
require('x');
var y = require('y');
var z;
z = require('z').initialize();
// requiring a module and using it in a function is ok
var fs = require('fs');
function readFile(filename, callback) {
fs.readFile(filename, callback)
}
要求回调函数中有容错处理
"handle-callback-err": 1
好的做法:
function loadData (err, data) {
if (err) {
console.log(err.stack);
}
doSomething();
}
function generateError (err) {
if (err) {}
}
禁止混合常规变量声明和 require 调用
"no-mixed-requires": 1
示例:
// BAD
var fs = require('fs'),
i = 0;
var async = require('async'),
debug = require('diagnostics').someFunction('my-module'),
eslint = require('eslint');
// GOOD
var foo = 42,
bar = 'baz';
var foo = require('foo' + VERSION),
bar = require(getBarModuleName()),
baz = require();
不允许 new require
"no-new-require": "error"
示例:
// BAD
`var appHeader = new require('app-header');`
// GOOD
var AppHeader = require('app-header');
var appHeader = new AppHeader();
当使用 _dirname
和 _filename
时不允许字符串拼接
"no-path-concat": "error"
示例:
// BAD
var fullPath = __dirname + "/foo.js";
var fullPath = __filename + "/foo.js";
// GOOD
var fullPath = dirname + "/foo.js";
ECMAScript 6 相关规范
不允许修改类声明的变量
"no-class-assign": 2
错误示范:
class A { }
A = 0;
禁止在可能与比较操作符相混淆的地方使用箭头函数
"no-confusing-arrow": "error"
示范:
// BAD
var x = a => 1 ? 2 : 3;
var x = (a) => 1 ? 2 : 3;
var x = (a) => (1 ? 2 : 3);
// GOOD
var x = a => (1 ? 2 : 3);
var x = (a) => (1 ? 2 : 3);
var x = a => { return 1 ? 2 : 3; };
var x = (a) => { return 1 ? 2 : 3; };
不允许改变用const声明的变量
"no-const-assign": "error"
禁止类成员中出现重复的名称
"no-dupe-class-members": 2
错误示范:
const a = 0;
a = 1;
禁止类成员中出现重复的名称
"no-duplicate-imports": 2
禁止 Symbolnew 操作符和 new 一起使用
"no-new-symbol": 2
示例:
// BAD
var foo = new Symbol('foo');
// GOOD
var foo = Symbol('foo');
function bar(Symbol) {
const baz = new Symbol("baz");
}
在构造函数中禁止在调用 super() 之前使用 this 或 super
"no-this-before-super": "error"
错误示范:
class A extends B {
constructor() {
this.a = 0;
super();
}
}
class A extends B {
constructor() {
this.foo();
super();
}
}
class A extends B {
constructor() {
super.foo();
super();
}
}
class A extends B {
constructor() {
super(this.foo());
}
}
好的做法:
class A {
constructor() {
this.a = 0; // OK, this class doesn't have an `extends` clause.
}
}
class A extends B {
constructor() {
super();
this.a = 0; // OK, this is after `super()`.
}
}
class A extends B {
foo() {
this.a = 0; // OK. this is not in a constructor.
}
}
禁止在对象中使用不必要的计算属性
"no-useless-computed-key": 2
错误示范:
var a = { ['0']: 0 };
var a = { ['0+1,234']: 0 };
var a = { [0]: 0 };
var a = { ['x']: 0 };
var a = { ['x']() {} };
好的做法:
var c = { 'a': 0 };
var c = { 0: 0 };
var a = { x() {} };
var c = { a: 0 };
var c = { '0+1,234': 0 };
禁止在 import 和 export 和解构赋值时将引用重命名为相同的名字
"no-useless-rename": 2
错误示范:
import { foo as foo } from "bar";
export { foo as foo };
export { foo as foo } from "bar";
let { foo: foo } = bar;
let { 'foo': foo } = bar;
function foo({ bar: bar }) {}
({ foo: foo }) => {}
要求使用 let 或 const 而不是 var
"no-var": 1
要求 generator 函数内有 yield
"require-yield": 1
示例:
// BAD
function* foo() {
return 10;
}
// GOOD
function* foo() {
yield 5;
return 10;
}
function foo() {
return 10;
}
要求 symbol 描述
"symbol-description": 1
示范:
// BAD
var foo = Symbol();
// GOOD
var foo = Symbol("some description");
var someString = "some description";
var bar = Symbol(someString);