推荐的 JS 代码规范,以及 ESLlint 配置及其说明

本文详细介绍了JavaScript编程中的代码规范,包括必须遵循的规则如避免在循环中使用await、禁止使用异步函数作为Promise executor等,以及建议执行的最佳实践,旨在帮助开发者写出更高质量的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值