Skip to content

Latest commit

 

History

History
4347 lines (3172 loc) · 75.9 KB

eslint-ecomfe-rules.md

File metadata and controls

4347 lines (3172 loc) · 75.9 KB

JavaScript Style

eslint-config-ecomfe

Overview

Rules

可能的错误或逻辑错误

  • 禁止方向错误的 for 循环

    eslint: for-direction

    // ✓ ok
    for (var i = 0; i < 10; i++) { ... }
    
    // ✗ avoid
    for (var i = 0; i < 10; i--) { ... }
    
    for (var i = 10; i >= 0; i++) { ... }
  • getter 必须有返回值,并且禁止返回空

    eslint: getter-return

    // ✓ ok
    p = {
        get name(){
            return "nicholas";
        }
    };
    
    Object.defineProperty(p, "age", {
        get: function (){
            return 18;
        }
    });
    
    class P{
        get name(){
            return "nicholas";
        }
    }
    
    // ✗ avoid
    p = {
        get name(){
            // no returns.
        }
    };
    
    Object.defineProperty(p, "age", {
        get: function (){
            // no returns.
        }
    });
    
    class P {
        get name(){
            // no returns.
        }
    }
  • 允许在循环里使用await

    eslint: no-await-in-loop

    reason: 要求太严格了,有时需要在循环中写 await

    // ✓ ok
    async function foo(things) {
      const results = [];
      for (const thing of things) {
        results.push(await bar(thing));
      }
      return baz(results);
    }
  • 禁止与负零进行比较

    eslint: no-compare-neg-zero

    // ✓ ok
    if (x === 0) { ... }
    
    if (Object.is(x, -0)) { ... }
    
    // ✗ avoid
    if (x === -0) { ... }
  • 禁止条件语句中出现赋值语句

    eslint: no-cond-assign

    // ✓ ok
    if (x === 0) { ... }
    
    // ✗ avoid
    if (x = 0) { ... }
    
    while (x = 0) { ... }
  • 允许使用 console

    eslint: no-console

    reason: 脚手架保障build过程中去除 console

    // ✓ ok
    console.log("Log a debug level message.");
  • 禁止将常量作为分支条件判断中的测试表达式,但允许作为循环条件判断中的测试表达式

    eslint: no-constant-condition

    // ✓ ok
    if (x === 0) { ... }
    
    while (true) { ... }
    
    // ✗ avoid
    if (false) { ... }
  • 允许在正则表达式中使用控制字符

    在 ASCII 中,0-31 范围内的控制字符是特殊的、不可见的字符。

    !控制字符并不是 Ctrl 键的ASCII 表示,咱们 eslintrc.js 里的相应注释应该是理解错误。

    eslint: no-control-regex

    reason: 几乎不会遇到这种场景。

    // ✓ ok
    var pattern1 = /\x1f/;
    var pattern2 = new RegExp("\x1f");
  • 允许使用 debugger

    eslint: no-debugger

    reason: 脚手架保障build过程中去除。

    // ✓ ok
    function isTruthy(x) {
        debugger;
        return Boolean(x);
    }
  • 禁止在 function 定义中出现重复的参数

    eslint: no-dupe-args

    // ✓ ok
    function foo(a, b, c) {
        console.log(a, b, c);
    }
    
    var bar = function (a, b, c) {
        console.log(a, b, c);
    };
    
    // ✗ avoid
    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);
    };
  • 禁止在对象字面量中出现重复的键名

    no-dupe-keys

    // ✓ ok
    var foo = {
        bar: "baz",
        quxx: "qux"
    };
    
    // ✗ avoid
    var foo = {
        bar: "baz",
        bar: "qux"
    };
    
    var foo = {
        "bar": "baz",
        bar: "qux"
    };
  • 禁止在 switch 语句中出现重复测试表达式的 case

    eslint: no-duplicate-case

    switch (id) {
        case 1:
        // ...
        case 1:   // ✗ avoid
    }
  • 禁止出现空代码块,允许 catch 为空代码块

    eslint: no-empty

    // ✓ ok
    if (foo) {
    	...
    }
    
    while (foo) {
    	...
    }
      
    // ✗ avoid
    if (foo) {  }
    
    while (foo) {  }
    
    switch(foo) {  }
  • 禁止在正则表达式中使用空的字符集 []

    eslint: no-empty-character-class

    // ✓ ok
    /^abc[a-z]/.test("abcdefg"); // true
    "abcdefg".match(/^abc[a-z]/); // ["abcd"]
      
    // ✗ avoid
    /^abc[]/.test("abcdefg"); // false
    "abcdefg".match(/^abc[]/); // null
  • 禁止对 catch 子句的参数重新赋值

    eslint: no-ex-assign

    // ✓ ok
    try {
        // ...
    } catch (e) {
        const newVal = 'new value';
    }
    
    // ✗ avoid
    try {
        // ...
    } catch (e) {
        e = 'new value';
    }
  • 禁止不必要的布尔转换

    eslint: no-extra-boolean-cast

    // ✓ ok
    const result = true
    if (result) { ... }
    
    // ✗ avoid
    const result = true
    if (!!result) { ... }
  • 禁止将一个函数声明重新赋值

    eslint: no-func-assign

    // ✓ ok 
    var foo = function () {}
    foo = bar;
    
    function foo(foo) {
        foo = bar;
    }
    
    function foo() {
        var foo = bar;
    }
    
    // ✗ avoid
    function foo() {}
    foo = bar;
    
    function foo() {
        foo = bar;
    }
  • 禁止在嵌套的块中出现var变量声明或函数声明

    eslint: no-inner-declarations

    // ✓ ok 
    function doSomething() { }
    
    if (foo) {
        let bar1;
      	const hello = 'world';
    }
    
    // ✗ avoid
    if (test) {
        function doSomethingElse () { }
    }
    
    while (test) {
        var bar2;
    }
  • 禁止在 RegExp 构造函数中出现非法的正则表达式

    eslint: no-invalid-regexp

    RegExp('[a-z]');    // ✓ ok
    RegExp('[a-z');     // ✗ avoid
  • 禁止使用特殊空白符(比如全角空格),除非是出现在字符串、正则表达式或模版字符串中

    eslint: no-irregular-whitespace

    str = ' <NBSP>thing';							// ✓ ok
    function myFunc() /*<NBSP>*/{}   	// ✗ avoid
  • 禁止将 Math, JSON 或 Reflect 直接作为函数调用

    eslint: no-obj-calls

    // ✓ ok
    function area(r) {
        return Math.PI * r * r;
    }
    var object = JSON.parse("{}");
    var value = Reflect.get({ x: 1, y: 2 }, "x");
    
    // ✗ avoid
    var math = Math();
    var json = JSON();
    var reflect = Reflect();
  • 禁止直接使用 hasOwnProperty, isPrototypeOf 或 propertyIsEnumerable

    eslint: no-prototype-builtins

    该规则原意是禁止在直接对象实例上调用 Object.prototype 的一些方法。咱们eslintrc.js文件里的配置及相关注释应该是理解错误,应修改对应配置项。

      // ✓ ok
      var hasBarProperty = Object.prototype.hasOwnProperty.call(foo, "bar");
      
      var isPrototypeOfBar = Object.prototype.isPrototypeOf.call(foo, bar);
      
      var barIsEnumerable = {}.propertyIsEnumerable.call(foo, "bar");
      
      // ✗ avoid
      var hasBarProperty = foo.hasOwnProperty("bar");
      
      var isPrototypeOfBar = foo.isPrototypeOf(bar);
      
      var barIsEnumerable = foo.propertyIsEnumerable("bar");
  • 禁止正则表达式字面量中出现多个空格

    eslint: no-regex-spaces

    // ✓ ok
    var re = /foo {3}bar/;
    var re = new RegExp("foo {3}bar");
    
    // ✗ avoid
    var re = /foo   bar/;
    var re = new RegExp("foo   bar");
  • 禁止在数组中出现连续的逗号

    eslint: no-sparse-arrays

    // ✓ ok
    var items = [];
    var items = new Array(23);
    var colors = [ "red", "blue", ];
    
    // ✗ avoid
    var items = [,];
    var colors = [ "red",, "blue" ];
  • 禁止在普通字符串中出现模版字符串里的变量形式

    eslint: no-template-curly-in-string

    // ✓ ok
    `Hello ${name}!`;
    `Time: ${12 * 60 * 60 * 1000}`;
    
    templateFunction`Hello ${name}`;
    
    // ✗ avoid
    "Hello ${name}!";
    'Hello ${name}!';
    "Time: ${12 * 60 * 60 * 1000}";
  • 禁止在 return, throw, break 或 continue 之后还有代码

    eslint: no-unreachable

    // ✗ avoid
    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 中出现 return, throw, break 或 continue

    eslint: no-unsafe-finally

    finally 中的语句会在 try 之前执行。

    // ✓ ok
    let foo = function() {
        try {
            return 1;
        } catch(err) {
            return 2;
        } finally {
            console.log("hola!");
        }
    };
    
    // ✗ avoid
    let foo = function() {
        try {
            return 1;
        } catch(err) {
            return 2;
        } finally {
            return 3;
        }
    };
  • 禁止在 in 或 instanceof 操作符的左侧变量前使用感叹号

    eslint: no-unsafe-negation

    if (!key in obj) { ... } // ✗ avoid
  • 必须使用 isNaN(foo) 而不是 foo === NaN。

    eslint: use-isnan

    if (isNaN(foo)) { ... }		// ✓ ok
    if (foo === NaN) { ... }	// ✗ avoid
  • 强制 typeof 表达式比较的对象必须是 "undefined", "object", "boolean", "number", "string", "function", "symbol", 或 "bigint"

    eslint: valid-typeof

    // ✓ ok
    typeof foo === "string"
    typeof bar == "undefined"
    typeof foo === baz
    typeof bar === typeof qux
    
    // ✗ avoid
    typeof foo === "strnig"
    typeof foo == "undefimed"
    typeof bar != "nunber"
    typeof bar !== "fucntion"

最佳实践

  • setter 必须有对应的 getter,getter 可以没有对应的 setter

    eslint: accessor-pairs

    // ✓ ok
    var o = {
        set a(value) {
            this.val = value;
        },
        get a() {
            return this.val;
        }
    };
    
    // ✗ avoid
    var o = {
        set a(value) {
            this.val = value;
        }
    };
  • 数组的方法除了 forEach 之外,回调函数必须有返回值

    eslint: array-callback-return

    // ✓ ok
    var bar = foo.map(node => node.getAttribute("id"));
    
    var foo = Array.from(nodes, function(node) {
        if (node.tagName === "DIV") {
            return true;
        }
        return false;
    });
    
    // ✗ avoid
    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 定义的变量,允许在块外使用

    eslint: block-scoped-var

    reason: 已经禁止使用 var 了。

  • 在类的非静态方法中,可以不存在对 this 的引用

    eslint: class-methods-use-this

    // ✓ ok
    class A {
        foo() {
            console.log("Hello World");
        }
    }
  • 禁止函数的圈复杂度超过20

    https://en.wikipedia.org/wiki/Cyclomatic_complexity

    圈复杂度数量上表现为源代码的独立执行路径的条数

    ps: 在程序流程图上更容易看出。

    eslint: complexity

  • 允许函数在不同分支返回不同类型的值

    reason: 缺少 TypeScript 的支持,类型判断是不准确的

    eslint: consistent-return

    // ✓ ok
    function doSomething(condition) {
        if (condition) {
            return true;
        } else {
            return 666;
        }
    }
  • 强制所有控制语句使用一致的括号风格, if、else、for、while、do

    eslint: curly

    // ✓ ok
    if (foo) {
        foo++;
    }
    
    // ✗ avoid
    if (foo) foo++;
    
    if (foo) {
        baz();
    } else qux();
  • switch 语句必须有 default

    eslint: default-case

    // ✓ ok
    switch (a) {
        case 1:
            /* code */
            break;
    
        default:
            /* code */
            break;
    }
    
    // ✗ avoid
    switch (a) {
        case 1:
            /* code */
            break;
    }
  • 点跟着属性换行

    eslint: dot-location

    // ✓ ok
    var foo = object
    .property;
    var bar = object.property;
    
    // ✗ avoid
    var foo = object.
    property;
  • 必须使用 ===!==,禁止使用 ==!=

    eslint: eqeqeq

    // ✓ ok
    a === b
    a !== b
    
    // ✗ avoid
    a == b
    a != b
  • for in 内部可以没有 hasOwnProperty

    eslint: guard-for-in

    // ✓ ok
    for (key in foo) {
        doSomething(key);
    }
  • 禁止使用 caller 或 callee

    它们是已废弃的语法

    eslint: no-caller

    // ✓ ok
    function foo(n) {
        if (n <= 0) {
            return;
        }
    
        foo(n - 1);
    }
    
    [1,2,3,4,5].map(function factorial(n) {
        return !(n > 1) ? 1 : factorial(n - 1) * n;
    });
    
    // ✗ avoid
    function foo(n) {
      	...
    
        arguments.callee(n - 1);
    }
    
    [1,2,3,4,5].map(function(n) {
        return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
    });
  • switch 的 case 内有变量定义的时候,必须使用大括号将 case 内变成一个代码块

    eslint: no-case-declarations

    // ✓ ok
    switch (foo) {
        case 1: {
            let x = 1;
            break;
        }
        case 2: {
            const y = 2;
            break;
        }
        case 3: {
            function f() {}
            break;
        }
        case 4:
            var z = 4;
            break;
        default: {
            class C {}
        }
    }
    
    // ✗ avoid
    switch (foo) {
        case 1:
            let x = 1;
            break;
        case 2:
            const y = 2;
            break;
        case 3:
            function f() {}
            break;
        default:
            class C {}
    }
  • 禁止在正则表达式中出现形似除法操作符的开头,如 let a = /=foo/

    eslint: no-div-regex

    // ✓ ok
    function bar() { return /[=]foo/; }
    
    // ✗ avoid
    function bar() { return /=foo/; }
  • 允许 if 语句中 return 语句之后有 else 块

    eslint: no-else-return

    // ✓ ok
    function foo() {
        if (x) {
            return y;
        } else {
            return z;
        }
    }
  • 允许有空函数

    eslint: no-empty-function

    reason: 有时需要将一个空函数设置为某个项的默认值。

    // ✓ ok
    function func(callback = function () {}) {
      ...
    }
  • 禁止使用空解构模式

    eslint: no-empty-pattern

    // ✓ ok
    var {a = {}} = foo;
    var {a = []} = foo;
    function foo({a = {}}) {}
    function foo({a = []}) {}
    
    // ✗ avoid
    var {} = foo;
    var [] = foo;
    var {a: {}} = foo;
    var {a: []} = foo;
    function foo({}) {}
    function foo([]) {}
    function foo({a: {}}) {}
    function foo({a: []}) {}
  • 禁止使用 foo == null,必须使用 foo === null

    eslint: no-eq-null

    // ✓ ok
    if (foo === null) { ... }
    
    while (qux !== null) { ... }
    
    // ✗ avoid
    if (foo == null) { ... }
    
    while (qux != null) { ... }
  • 禁止使用 eval

    eslint: no-eval

    // ✗ avoid
    var foo = eval;
    foo("var a = 0");
  • 禁止扩展原生类型

    eslint: no-extend-native

    // ✗ avoid
    Object.prototype.a = "a";
    Object.defineProperty(Array.prototype, "times", { value: 999 });
  • 禁止不必要的 .bind() 调用

    eslint: no-extra-bind

    // ✓ ok
    var x = function () {
        this.foo();
    }.bind(bar);
    
    var x = function (a) {
        return a + 1;
    }.bind(foo, bar);
    
    // ✗ avoid
    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);
  • 允许不必要的标签

    eslint: no-extra-label

    // ✓ ok
    A: while (a) {
        break A;
    }
    
    B: for (let i = 0; i < 10; ++i) {
        break B;
    }
    
    C: switch (a) {
        case 0:
            break C;
    }
  • 禁止 case 语句落空

    有意为之的落空需注释

    eslint: no-fallthrough

    // ✓ ok
    switch(foo) {
        case 1:
            doSomething();
            break;
    
        case 2:
            doSomething();
    }
    
    switch(foo) {
        case 1:
            doSomething();
            // 落空
    
        case 2:
            doSomething();
    }
    
    // ✗ avoid
    switch(foo) {
        case 1:
            doSomething();
    
        case 2:
            doSomething();
    }
  • 禁止数字字面量中使用前导和末尾小数点

    eslint: no-floating-decimal

    // ✓ ok
    var num = 0.5;
    var num = 2.0;
    var num = -0.7;
    
    // ✗ avoid
    var num = .5;
    var num = 2.;
    var num = -.7;
  • 禁止对原生对象或只读的全局对象进行赋值

    eslint: no-global-assign

    // ✓ ok
    a = 1
    var b = 1
    b = 2
    
    // ✗ avoid
    Object = null
    undefined = 1
  • 允许使用短符号进行类型转换

    eslint: no-implicit-coercion

    // ✓ ok
    var b = !!foo;
    var b = ~foo.indexOf(".");
    var n = +foo;
    var n = 1 * foo;
    var s = "" + foo;
    foo += ``;
  • 允许在全局范围内使用变量声明和 function 声明

    eslint: no-implicit-globals

    // ✓ ok
    var foo = 1;
    
    function bar() {}
  • 禁止使用类似 eval() 的方法

    eslint: no-implied-eval

    // ✓ ok
    setTimeout(function() {
        alert("Hi!");
    }, 100);
    
    setInterval(function() {
        alert("Hi!");
    }, 100);
    
    // ✗ avoid
    setTimeout("alert('Hi!');", 100);
    
    setInterval("alert('Hi!');", 100);
    
    execScript("alert('Hi!')");
    
    window.setTimeout("count = 5", 10);
    
    window.setInterval("foo = bar", 10);
  • 禁止 this 关键字出现在类和类对象之外

    eslint: no-invalid-this

    // ✓ ok
    function Foo() {
        // OK, this is in a legacy style constructor.
        this.a = 0;
        baz(() => this);
    }
    
    // ✗ avoid
    this.a = 0;
    baz(() => this);
  • 禁用 __iterator__ 属性

    eslint: no-iterator

    __iterator__ 是一个已废弃的属性,使用 [Symbol.iterator] 替代它

    // ✓ ok
    var __iterator__ = foo;
    
    // ✗ avoid
    Foo.prototype.__iterator__ = function() {
        return new FooIterator(this);
    };
    
    foo.__iterator__ = function () {};
    
    foo["__iterator__"] = function () {};
  • 禁用标签语句

    eslint: no-labels

    // ✓ ok
    var f = {
        label: "foo"
    };
    
    // ✗ avoid
    label:
        while(true) {
            ...
        }
    
    label:
        while(true) {
            break label;
        }
  • 禁用不必要的嵌套块

    eslint: no-lone-blocks

    // ✓ ok
    while (foo) {
        bar();
    }
    
    // ✗ avoid
    while (foo) {
        bar();
        {
            baz();
        }
    }
  • 允许在在循环内的函数内部出现外部定义的变量

    eslint: no-loop-func

    // ✓ ok
    for (var i=10; i; i--) {
        (function() { return i; })();
    }
  • 允许使用 magic numbers

    魔术数字是在代码中多次出现的没有明确含义的数字。(最好用命名常量取代它)

    eslint: no-magic-numbers

    // ✓ ok
    var dutyFreePrice = 100,
        finalPrice = dutyFreePrice + (dutyFreePrice * 0.25);
  • 禁止使用多个空格

    eslint: no-multi-spaces

    // ✓ ok
    var a = 1;
    
    if(foo === "bar") {}
    
    a << b
    
    var arr = [1, 2];
    
    a ? b: c
    
    // ✗ avoid
    var a =  1;
    
    if(foo   === "bar") {}
    
    a <<  b
    
    var arr = [1,  2];
    
    a ?  b: c
  • 禁止使用多行字符串

    eslint: no-multi-str

    // ✓ ok
    var x = "Line 1\n" +
            "Line 2";
    
    // ✗ avoid
    var x = "Line 1 \
             Line 2";
  • 禁止直接 new 一个类而不赋值

    eslint: no-new

    // ✓ ok
    var thing = new Thing();
    
    Thing();
    
    // ✗ avoid
    new Thing();
  • 禁止使用 new Function

    eslint: no-new-func

    // ✓ ok
    var x = function (a, b) {
        return a + b;
    };
    
    // ✗ avoid
    var x = new Function("a", "b", "return a + b");
    var x = Function("a", "b", "return a + b");
  • 禁止使用 new 来生成 String, Number 或 Boolean

    eslint: no-new-wrappers

    // ✓ ok
    var text = String(someValue);
    var num = Number(someValue);
    
    var object = new MyString();
    
    // ✗ avoid
    var stringObject = new String("Hello world");
    var numberObject = new Number(33);
    var booleanObject = new Boolean(false);
  • 禁用八进制字面量

    eslint: no-octal

    // ✓ ok
    var num  = "071";
    
    // ✗ avoid
    var num = 071;
    var result = 5 + 07;
  • 禁止在字符串中使用八进制转义序列

    eslint: no-octal-escape

    // ✓ ok
    var foo = "Copyright \u00A9";   // unicode
    
    var foo = "Copyright \xA9";     // 十六进制
    
    // ✗ avoid
    var foo = "Copyright \251";
  • 禁止对 function 的参数进行重新赋值

    eslint: no-param-reassign

    // ✓ ok
    function foo(bar) {
        var baz = bar;
    }
    
    // ✗ avoid
    function foo(bar) {
        bar = 13;
    }
  • 禁用 __proto__ 属性

    eslint: no-proto

    // ✓ ok
    var a = Object.getPrototypeOf(obj);
    
    Object.setPrototypeOf(obj, b);
    
    var c = { __proto__: a };
    
    // ✗ avoid
    var a = obj.__proto__;
    
    var a = obj["__proto__"];
    
    obj.__proto__ = b;
    
    obj["__proto__"] = b;
  • 禁止多次声明同一变量

    eslint: no-redeclare

    // ✓ ok
    var a = 3;
    a = 10;
    
    // ✗ avoid
    var a = 3;
    var a = 10;
  • 允许使用对象的某些属性

    eslint: no-restricted-properties

    // ✓ ok
    foo.__defineGetter__(bar, baz);
  • 禁止在 return 语句中使用赋值语句

    eslint: no-return-assign

    // ✓ ok
    function doSomething() {
        return foo === bar + 2;
    }
    
    // ✗ avoid
    function doSomething() {
        return foo = bar + 2;
    }
    
    function doSomething() {
        return foo += 2;
    }
    
    function doSomething() {
        return (foo = bar + 2);
    }
  • 允许出现 location.href = "javascript:void(0)"

    eslint: no-script-url

    reason: 有些场景下还是需要用到这个

    // ✓ ok
    location.href = "javascript:void(0)";
  • 禁止将自己赋值给自己

    eslint: no-self-assign

    // ✓ ok
    foo = bar;
    [a, b] = [b, a];
    
    // ✗ avoid
    foo = foo;
    
    [a, b] = [a, b];
    
    [a, ...b] = [x, ...b];
    
    ({a, b} = {a, x});
  • 禁止将自己与自己比较

    eslint: no-self-compare

    // ✗ avoid
    var x = 10;
    if (x === x) {
        x = 20;
    }
  • 禁止使用逗号操作符

    eslint: no-sequences

    此规则禁止逗号操作符的使用,以下情况除外:

    • 在初始化或者更新部分 for 语句时。
    • 如果表达式序列被明确包裹在括号中。
    // ✓ ok
    foo = (doSomething(), val);
    
    for (i = 0, j = 10; i < j; i++, j--);
    
    // ✗ avoid
    foo = doSomething(), val;
    
    for (; doSomething(), !!test; );
  • 禁止抛出异常字面量

    eslint: no-throw-literal

    // ✓ ok
    throw new Error("error");
    
    var e = new Error("error");
    throw e;
    
    try {
        throw new Error("error");
    } catch (e) {
        throw e;
    }
    
    // ✗ avoid
    throw "error";
    
    throw 0;
    
    throw undefined;
    
    throw null;
  • 禁用一成不变的循环条件

    eslint: no-unmodified-loop-condition

    // ✓ ok
    while (node) {
        doSomething(node);
        node = node.parent;
    }
    
    for (var j = 0; j < items.length; ++j) {
        doSomething(items[j]);
    }
    
    // ✗ avoid
    while (node) {
        doSomething(node);
    }
    node = other;
    
    for (var j = 0; j < items.length; ++i) {
        doSomething(items[j]);
    }
    
    while (node !== root) {
        doSomething(node);
    }
  • 禁止出现未使用过的表达式

    eslint: no-unused-expressions

    // ✓ ok
    f()
    
    a = 0
    
    // ✗ avoid
    n + 1
  • 禁止出现没用到的 label (已经禁止使用 label 了)

    eslint: no-unused-labels

  • 禁止不必要的 .call().apply()

    eslint: no-useless-call

    // ✓ ok
    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]);
    
    // ✗ avoid
    foo.call(undefined, 1, 2, 3);
    foo.apply(undefined, [1, 2, 3]);
    foo.call(null, 1, 2, 3);
    foo.apply(null, [1, 2, 3]);
    obj.foo.call(obj, 1, 2, 3);
    obj.foo.apply(obj, [1, 2, 3]);
  • 禁止不必要的 catch 子句

    eslint: no-useless-catch

    // ✓ ok
    try {
      doSomethingThatMightThrow();
    } catch (e) {
      handleError(e);
    }
    
    try {
      doSomethingThatMightThrow();
    } catch (e) {
      doSomethingBeforeRethrow();
      throw e;
    }
    
    // ✗ avoid
    try {
      doSomethingThatMightThrow();
    } catch (e) {
      throw e;
    }
  • 禁止不必要的字符串字面量或模板字面量的连接

    eslint: no-useless-concat

    // ✓ ok
    var c = a + b;
    var c = '1' + a;
    var a = 1 + '1';
    var c = 1 - 2;
    var c = "foo" +
        "bar";
    
    // ✗ avoid
    var a = `some` + `string`;
    var a = '1' + '0';
    var a = '1' + `0`;
    var a = `1` + '0';
    var a = `1` + `0`;
  • 禁用不必要的转义字符

    eslint: no-useless-escape

    // ✓ ok
    "\"";
    '\'';
    "\x12";
    "\u00a9";
    "\371";
    "xs\u2111";
    `\``;
    `\${${foo}}`;
    `$\{${foo}}`;
    /\\/g;
    /\t/g;
    /\w\$\*\^\./;
    
    // ✗ avoid
    "\'";
    '\"';
    "\#";
    "\e";
    `\"`;
    `\"${foo}\"`;
    `\#{foo}`;
    /\!/;
    /\@/;
  • 禁止多余的 return 语句

    eslint: no-useless-return

    // ✓ ok
    function foo() { return 5; }
    
    // ✗ avoid
    function foo() { return; }
  • 禁用 void 操作符

    eslint: no-void

    // ✗ avoid
    void foo
    
    var foo = void bar();
  • 允许在注释中使用特定的警告术语TODO和FIXME

    eslint: no-warning-comments

    function callback(err, results) {
      if (err) {
        console.error(err);
        return;
      }
      // TODO														// ✓ ok
    }
  • 禁用 with 语句

    eslint: no-with

    // ✓ ok
    const r = ({x, y}) => Math.sqrt(x * x + y * y);
    
    // ✗ avoid
    with (point) {
        r = Math.sqrt(x * x + y * y); // is r a member of point?
    }
  • Promise 的 reject 中必须传入 Error 对象,而不是字面量

    eslint: prefer-promise-reject-errors

    // ✓ ok
    Promise.reject(new Error("something bad happened"));
    
    new Promise(function(resolve, reject) {
      reject(new Error("something bad happened"));
    });
    
    // ✗ avoid
    Promise.reject("something bad happened");
    
    new Promise(function(resolve, reject) {
      reject("something bad happened");
    });
  • 强制在 parseInt() 使用基数参数

    eslint: radix

    // ✓ ok
    var num = parseInt("071", 10);
    
    var num = parseInt("071", 8);
    
    // ✗ avoid
    var num = parseInt("071");
    
    var num = parseInt(someValue);
    
    var num = parseInt("071", "abc");
    
    var num = parseInt();
  • 禁止使用不带 await 表达式的 async 函数

    eslint: require-await

    // ✓ ok
    async function foo() {
        await doSomething();
    }
    
    bar(async () => {
        await doSomething();
    });
    
    // ✗ avoid
    async function foo() {
        doSomething();
    }
    
    bar(async () => {
        doSomething();
    });
  • 允许所有的 var 声明不在它们所在的作用域顶部

    eslint: vars-on-top

    // ✓ ok
    function doSomething() {
        for (var i=0; i<10; i++) {}
    }
    
    function doSomething() {
        var first;
        if (true) {
            first = true;
        }
        var second;
    }
  • 必须使用 if (foo === 5) 而不是 if (5 === foo)

    eslint: yoda

    // ✓ ok
    if (5 & value) { ... }
    
    if (value === "red") { ... }
    
    // ✗ avoid
    if (true == flag) { ... }
    
    if (5 > count) { ... }

严格模式

  • 禁止使用 "strict",除了全局统一

    eslint: strict

    // ✓ ok
    "use strict";
    
    function foo() {
    }
    
    // ✗ avoid
    function foo() {
        "use strict";
    }

变量

  • 允许变量在定义的时候可以不赋值

    eslint: init-declarations

    // ✓ ok
    var bar;
  • 允许 catch 子句的参数与外层作用域中的变量同名

    eslint: no-catch-shadow

    已弃用,被no-shadow替代

    // ✓ ok
    var err = "x";
    
    try {
        throw "problem";
    } catch (err) {
    
    }
  • 禁止对一个变量使用 delete

    eslint: no-delete-var

    // ✗ avoid
    var x;
    delete x;
  • 禁止 label 名称与已定义的变量重复 (已经禁止使用 label 了)

    eslint: no-label-var

  • 允许使用全局变量

    eslint: no-restricted-globals

    // ✓ ok
    var event = 1;		// 声明一个自定义全局变量
  • 允许变量名与上层作用域内的已定义的变量重复

    eslint: no-shadow

    reason:很多时候函数的形参和传参是同名的

    // ✓ ok
    var a = 3;
    function b() {
        var a = 10;
    }
    
    if (true) {
        let a = 5;
    }
  • 禁止使用关键字作为变量名

    eslint: no-shadow-restricted-names

    // ✓ ok
    function f(a, b){}
    
    // ✗ avoid
    function NaN(){}
    
    !function(Infinity){};
    
    var undefined = 5;
    
    try {} catch(eval){}
  • 禁止使用未定义的变量

    eslint: no-undef

    // ✓ ok
    var b = 666;
    b = 10;
    
    // ✗ avoid
    var a = someFunction();
    b = 10;
  • 禁止将变量初始化为 undefined

    eslint: no-undef-init

    // ✓ ok
    var foo = 100;
    let bar = 200;
    
    // ✗ avoid
    var foo = undefined;
    let bar = undefined;
  • 允许使用 undefined

    eslint: no-undefined

    // ✓ ok
    if (foo === undefined) {
        ...
    }
  • 禁止出现未使用过的变量

    eslint: no-unused-vars

    // ✓ ok
    var x = 10;
    alert(x);
    
    // ✗ avoid
    some_unused_var = 42;
  • 变量必须先定义后使用

    eslint: no-use-before-define

    // ✓ ok
    var a = 10;
    alert(a);
    
    // ✗ avoid
    alert(a);
    var a = 10;

Node.js 和 CommonJS

这些规则是关于Node.js 或 在浏览器中使用CommonJS 的:

  • 不强制 callback 之后必须立即 return

    eslint: callback-return

    // ✓ ok
    function foo(err, callback) {
        if (err) {
            callback(err);
        }
        callback();
    }
    
    function foo(err, callback) {
        if (err) {
            return callback(err);
        }
        callback();
    }
  • 不强制 require 必须在全局作用域下

    eslint: global-require

    // ✓ ok
    function readFile(filename, callback) {
        var fs = require('fs');			// ✓ ok
        fs.readFile(filename, callback)
    }
  • 不强制 callback 中的 err 必须被处理

    eslint: handle-callback-err

    reason: 它是通过字符串匹配来判断函数参数 err 的,不准确

    // ✓ ok
    function loadData (err, data) {
        doSomething();
    }
    
    function loadData (err, data) {
        if (err) {
            console.log(err.stack);
        }
        doSomething();
    }
  • 禁止直接使用 Buffer 构造函数

    eslint: no-buffer-constructor

    reason: Buffer 构造函数是已废弃的语法

    // ✓ ok
    Buffer.alloc(5);
    Buffer.allocUnsafe(5);
    Buffer.from([1, 2, 3]);
    
    // ✗ avoid
    new Buffer(5);
    new Buffer([1, 2, 3]);
    
    Buffer(5);
    Buffer([1, 2, 3]);
  • 不强制 require 必须放在一起

    eslint: no-mixed-requires

    // ✓ ok
    var fs = require('fs'),
        i = 0;
    
    var async = require('async'),
        debug = require('diagnostics').someFunction('my-module'),
        eslint = require('eslint');
  • 禁止直接 new require("foo")

    eslint: no-new-require

    // ✓ ok
    var AppHeader = require('app-header');
    var appHeader = new AppHeader();
    
    // ✗ avoid
    var appHeader = new require('app-header');
  • 禁止对 __dirname__filename 使用字符串连接

    eslint: no-path-concat

    reason: 不同平台下的路径符号不一致,建议使用 path 处理平台差异性

    // ✓ ok
    const path = require('path');
    var fullPath = path.join(__dirname, "foo.js");
    var fullPath = path.resolve(__dirname, "foo.js");
    
    // ✗ avoid
    var fullPath = __dirname + "/foo.js";
    
    var fullPath = __filename + "/foo.js";
  • 允许使用 process.env

    eslint: no-process-env

    // ✓ ok
    if(process.env.NODE_ENV === "development") {
        //...
    }
    
    var config = require("./config");
    
    if(config.env === "development") {
        //...
    }
  • 允许使用 process.exit(0)

    eslint: no-process-exit

    // ✓ ok
    process.exit(1);
    process.exit(0);
    
    Process.exit();
    var exit = process.exit;
  • 不限制使用Node.js的模块

    eslint: no-restricted-modules

    // ✓ ok
    var fs = require('fs');
    var cluster = require('cluster');
  • 允许使用 node 中的同步的方法,比如 fs.readFileSync

    eslint: no-sync

    // ✓ ok
    fs.existsSync(somePath);

代码风格

  • 如果数组元素内或元素间有换行,则要求换行

    eslint: array-element-newline

    // ✓ ok
    var a = [];
    var b = [1];
    var c = [1, 2];
    var d = [1, 2, 3];
    var e = [
        function foo() {
            dosomething();
        },
        function bar() {
            dosomething();
        }
    ];
    
    // ✗ avoid
    var d = [1,
        2, 3];
    var e = [
        function foo() {
            dosomething();
        }, function bar() {
            dosomething();
        }
    ];
  • 禁止在数组括号内出现空格

    eslint: array-bracket-spacing

    // ✓ ok
    var arr = [];
    var arr = ['foo', 'bar', 'baz'];
    var arr = [['foo'], 'bar', 'baz'];
    var arr = [
      'foo',
      'bar',
      'baz'
    ];
    
    var [x, y] = z;
    var [x,y] = z;
    
    // ✗ avoid
    var arr = [ 'foo', 'bar' ];
    var arr = ['foo', 'bar' ];
    var arr = [ ['foo'], 'bar'];
    var arr = [[ 'foo' ], 'bar'];
    var arr = [ 'foo',
      'bar'
    ];
    var [ x, y ] = z;
    var [ x,y ] = z;
  • 元素视长度自由控制换行,不强制

    eslint: array-element-newline

    // ✓ ok
    var c = [1, 2];
    var d = [1, 2, 3];
    
    var arr = [
        1,
        2,
        3
    ];
  • 大括号后要求使用一个或多个空格

    eslint: block-spacing

    // ✓ ok
    function foo() { return true; }
    if (foo) { bar = 0; }
    
    // ✗ avoid
    function foo() {return true;}
    if (foo) { bar = 0;}
    function baz() {let i = 0;
        return i;
    }
  • 在function,if,try等方法后使用统一的大括号风格

    eslint: brace-style

    // ✓ ok
    function foo () {
      return true;
    }
    
    if (foo) {
      bar();
    }
    
    if (foo) {
      bar();
    } else {
      baz();
    }
    
    try {
      somethingRisky();
    } catch(e) {
      handleError();
    }
    
    // ✗ avoid
    function foo()
    {
      return true;
    }
    
    if (foo)
    {
      bar();
    }
    
    try
    {
      somethingRisky();
    } catch(e)
    {
      handleError();
    }
    
    if (foo) {
      bar();
    }
    else {
      baz();
    }
  • 变量名使用驼峰命名

    eslint: camelcase

    // ✓ ok
    var myFavoriteColor   = "#112C85";
    var _myFavoriteColor  = "#112C85";
    var myFavoriteColor_  = "#112C85";
    const MY_FAVORITE_COLOR = "#112C85";
    
    // ✗ avoid
    var my_favorite_color = "#112C85";
  • 不要求注释必须大写开头

    eslint: capitalized-comments

    咱们通常是中文,所以不用了

  • 禁用拖尾逗号

    eslint: comma-dangle

    // ✓ ok
    var foo = {
        bar: "baz",
        qux: "quux"
    };
    
    var arr = [1, 2];
    
    // ✗ avoid
    var foo = {
        bar: "baz",
        qux: "quux",
    };
    
    var arr = [1, 2, ];
  • 逗号前不空格,后空格

    eslint: comma-spacing

    // ✓ ok
    var foo = 1, bar = 2;
    var arr = [1, 2];
    
    // ✗ avoid
    var foo = 1 ,bar = 2;
    var arr = [1 , 2];
    foo(a ,b);
  • 要求逗号放在数组元素、对象属性或变量声明之后,且在同一行

    eslint: comma-style

    // ✓ ok
    var foo = 1, bar = 2;
    
    var foo = 1,
        bar = 2;
    
    function bar() {
        return {
            "a": 1,
            "b:": 2
        };
    }
    
    // ✗ avoid
    var foo = 1
    ,
    bar = 2;
    
    var foo = 1
      , bar = 2;
    
    
    var foo = ["apples"
               , "oranges"];
    
    function bar() {
        return {
            "a": 1
            ,"b:": 2
        };
    }
  • 禁止在计算属性内使用空格

    eslint: computed-property-spacing

    // ✓ ok
    obj[foo]
    obj['foo']
    var x = {[b]: a}
    obj[foo[bar]]
    
    // ✗ avoid
    obj[foo ]
    obj[ 'foo']
    var x = {[ b ]: a}
  • this 的别名可以自定

    eslint: consistent-this

    // ✓ ok
    var self = this;
    var that = this;
    var _this = this;
  • 强制非空文件末尾至少存在一行空行 (LF)

    eslint: eol-last

    // ✓ ok
    function doSmth() {
      var foo = 2;
    }
    			// 文件末尾空行
    // ✗ avoid
    function doSmth() {
      var foo = 2;
    }
  • 禁止在函数调用时函数名和开括号之间有空格

    eslint: func-call-spacing

    // ✓ ok
    fn();
    
    // ✗ avoid
    fn ();
    
    fn
    ();
  • 函数名与赋值给它们的变量名或属性名相匹配

    eslint: func-name-matching

    // ✓ ok
    var foo = function foo() {};
    var foo = function() {};
    var foo = () => {};
    foo = function foo() {};
    
    obj.foo = function foo() {};
    obj['foo'] = function foo() {};
    obj['foo//bar'] = function foo() {};
    obj[foo] = function bar() {};
    
    var obj = {foo: function foo() {}};
    var obj = {[foo]: function bar() {}};
    var obj = {'foo//bar': function foo() {}};
    var obj = {foo: function() {}};
    
    obj['x' + 2] = function bar(){};
    var [ bar ] = [ function bar(){} ];
    ({[foo]: function bar() {}})
    
    module.exports = function foo(name) {};
    module['exports'] = function foo(name) {};
    
    // ✗ avoid
    var foo = function bar() {};
    foo = function bar() {};
    obj.foo = function bar() {};
    obj['foo'] = function bar() {};
    var obj = {foo: function bar() {}};
    ({['foo']: function bar() {}});
  • 函数表达式可以没有名字

    eslint: func--names

    // ✓ ok
    (function() {
        // ...
    }())
  • 允许使用 function 声明或函数表达式

    eslint: func-style

    // ✓ ok
    function foo() {
        // ...
    }
    
    // ✓ ok
    var foo = function() {
        // ...
    };
  • 如果函数的任一参数有换行,则要求在函数括号内换行。否则禁止换行

    eslint: function-paren-newline

    // ✓ ok
    function foo(bar, baz) {}
    
    var foo = function(
      bar,
      baz
    ) {};
    
    foo(
      bar,
      baz,
      qux
    );
    
    // ✗ avoid
    function foo(bar,
      baz
    ) {}
    
    var foo = function(
      bar, baz
    ) {};
    
    foo(bar,
      baz);
  • 除关键字和保留字外,不限制标识符的使用。

    eslint: id-blacklist

    // ✓ ok
    var data = {...};
    
    function callback() {
        // ...
    }
    
    var aBaBaB = 999;
    
    // ✗ avoid
    const class = 100;
    const if = 200;
  • 不限制标识符的最小和最大长度

    eslint: id-length

    // ✓ ok
    const a = 100;
    const aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa = 100
  • 不限制标识符的使用

    eslint: id-match

  • 禁止在箭头函数体之前出现换行

    eslint: implicit-arrow-linebreak

    // ✓ ok
    (foo) => bar;
    
    (foo) => (bar);
    
    (foo) => bar => baz;
    
    (foo) => (
      bar()
    );
    
    // ✗ avoid
    (foo) =>
      bar;
    
    (foo) =>
      (bar);
    
    (foo) =>
      bar =>
        baz;
    
    (foo) =>
    (
      bar()
    );
  • 四个空格缩进

    eslint: indent

    // ✓ ok
    if (a) {
        b=c;
        function foo(d) {
            e=f;
        }
    }
    
    // ✗ avoid
    if (a) {
      b=c;
      function foo(d) {
        e=f;
      }
    }
  • 强制所有不包含单引号的 JSX 属性值使用单引号

    eslint: jsx-quotes

    // ✓ ok
    <a b='c' />
    <a b="'" />
    
    // ✗ avoid
    <a b="c" />
  • 强制在冒号后只有一个空格

    eslint: key-spacing

    var obj = { "foo": 42 };		// ✓ ok
    
    var obj = { "foo" : 42 };		// ✗ avoid
  • 关键字和类似关键字的符号前后均有空格

    eslint: keyword-spacing

    // ✓ ok
    if (foo) {
        //...
    } else if (bar) {
        //...
    } else {
        //...
    }
    
    // ✗ avoid
    if (foo) {
        //...
    }else if (bar) {
        //...
    }else {
        //...
    }
  • 不强制注释之前或之后是否应该有空行

    eslint: lines-around-comment

    // ✓ ok
    var night = "long";
    /* what a great and wonderful day */
    var day = "great"
    // ✓ ok
    var night = "long";
    
    /* what a great and wonderful day */
    var day = "great"
    // ✓ ok
    var night = "long";
    
    /* what a great and wonderful day */
    
    var day = "great"
  • 要求在类成员之后有一行空行

    eslint: lines-between-class-members

    // ✓ ok
    class MyClass {
      foo() {
        //...
      }
    
      bar() {
        //...
      }
    }
    
    // ✗ avoid
    class MyClass {
      foo() {
        //...
      }
      bar() {
        //...
      }
    }
  • 不强制块语句的最大可嵌套深度

    eslint: max-depth

    // ✓ ok
    function foo() {
        for (;;) { // Nested 1 deep
            let val = () => (param) => { // Nested 2 deep
               if (true) { // Nested 3 deep
                    if (true) { // Nested 4 deep
                      ...
                    }
                }
            };
        }
    }
  • 不强制一行的最大长度

    eslint: max-len

  • 不强制一个文件的最大行数

    eslint: max-lines

  • 不强制回调函数最大嵌套深度

    eslint: max-nested-callbacks

    // ✓ ok
    foo(function () {
        bar(function () {
            baz(function() {
                qux(function () {
    							...
                });
            });
        });
    });
  • 不强制函数定义中最大参数个数

    eslint: max-params

    // ✓ ok
    function f(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) {
      ...
    }
  • 不强制一个函数中所允许允许的最大语句数量

    eslint: max-statements

  • 强制每一行中所允许的最大语句数量为 1

    eslint: max-statements-per-line

    // ✓ ok
    var bar, baz;
    if (condition) bar = 1;
    
    // ✗ avoid
    var bar; var baz;
    if (condition) { bar = 1; }
  • 不要求多行注释使用唯一的风格

    eslint: multiline-comment-style

    // ✓ ok
    /*
     * 多行注释
     * 多行注释
     */
    
    /* 多行注释
     * 多行注释
     */
    
    // 多行注释
    // 多行注释
  • 不强制要求在三元操作数中间换行,看表达式长度自行决定

    eslint: multiline-ternary

    // ✓ ok
    foo > bar ?
        value1 :
        value2;
    
    foo > bar ? value1 : value2;
  • 构造函数名首字母大写

    eslint: new-cap

    var friend = new Person();	// ✓ ok
    
    var friend = new person();	// ✗ avoid
  • 要求调用无参构造函数时有圆括号

    eslint: new-parens

    // ✓ ok
    var person = new Person();
    var person = new (Person)();
    
    // ✗ avoid
    var person = new Person;
    var person = new (Person);
  • 方法链中的每个调用之后或或深度成员访问之后有一个换行符

    eslint: newline-per-chained-call

    // ✓ ok
    obj
      .prop.method()
      .method2()
      .method3().prop;
    
    // ✗ avoid
    obj.method().method2().method3();
    
    obj
      .chain({}).map(foo)
      .filter(bar);
  • 通常不允许使用 Array的构造函数来创建数组。唯一的例外是通过给构造函数传入指定的一个数值来创建稀疏数组

    eslint: no-array-constructor

    // ✓ ok
    new Array(someOtherArray.length)
    Array(500)
    
    // ✗ avoid
    new Array(0, 1, 2)
    Array(0, 1, 2)
  • 不禁止位运算

    eslint: no-bitwise

    通常是不用,没必要禁止

    // ✓ ok
    var x = y | z;
    
    var x = y & z;
    
    var x = y ^ z;
    
    var x = ~ z;
    
    var x = y << z;
    
    var x = y >> z;
    
    var x = y >>> z;
    
    x |= y;
    
    x &= y;
    
    x ^= y;
    
    x <<= y;
    
    x >>= y;
    
    x >>>= y;
  • 禁止使用 continue 语句

    eslint: no-continue

    // ✓ ok
    var sum = 0,
        i;
    
    for(i = 0; i < 10; i++) {
        if(i < 5) {
           sum += i;
        }
    }
    
    // ✗ avoid
    var sum = 0,
        i;
    
    for(i = 0; i < 10; i++) {
        if(i >= 5) {
            continue;
        }
    
        sum += i;
    }
  • 允许注释和代码出现在同一行

    eslint: no-inline-comments

    // ✓ ok
    var a = 1; // declaring a to 1
  • 禁止 if 语句作为唯一语句出现在 else 语句块中

    eslint: no-lonely-if

    // ✓ ok
    if (condition) {
        // ...
    } else if (anotherCondition) {
        // ...
    }
    
    // ✗ avoid
    if (condition) {
        // ...
    } else {
        if (anotherCondition) {
            // ...
        }
    }
  • 禁止混合使用不同的操作符

    eslint: no-mixed-operators

    // ✓ ok
    var foo = a || b || c;
    var foo = a && b && c;
    var foo = (a && b < 0) || c > 0 || d + 1 === 0;
    var foo = a && (b < 0 || c > 0 || d + 1 === 0);
    
    var foo = a + b - c;
    
    // ✗ avoid
    var foo = a && b < 0 || c > 0 || d + 1 === 0;
    var foo = a & b | c;
  • 禁止空格和 tab 的混合缩进

    eslint: no-mixed-spaces-and-tabs

    // ✓ ok
    function add(x, y) {
    // --->return x + y;
        return x + y;
    }
    
    // ✗ avoid
    function add(x, y) {
    // --->..return x + y;
    
          return x + y;
    }
    
    function main() {
    // --->var x = 5,
    // --->....y = 7;
    
        var x = 5,
            y = 7;
    }
  • 禁止在单行语句中使用多个赋值

    eslint: no-multi-assign

    // ✓ ok
    var a = 5;
    var b = a;
    
    // ✗ avoid
    var a = b = c = 5;
  • 允许否定表达式

    eslint:no-negated-condition

    // ✓ ok
    if (!a) {
        doSomething();
    }
  • 禁止使用嵌套的三元表达式

    eslint: no-nested-ternary

    // ✓ ok
    var thing = foo ? bar : foobar;
    
    // ✗ avoid
    var thing = foo ? bar : baz === qux ? quxx : foobar;
    
    foo ? baz === qux ? quxx() : foobar() : bar();
  • 禁用 Object 的构造函数

    eslint: no-new-object

    // ✓ ok
    var myObject = new CustomObject();
    
    var myObject = {};
    
    // ✗ avoid
    var myObject = new Object();
    
    var myObject = new Object;
  • 允许一元操作符 ++--

    eslint: no-plusplus

    // ✓ ok
    var foo = 0;
    foo++;
    
    var bar = 42;
    bar--;
    
    for (i = 0; i < l; i++) {
        return;
    }
  • 不限定不能使用的语法

    eslint: no-restricted-syntax

  • 允许使用 tab (制表符)

    eslint: no-tabs

  • 允许使用三元操作符

    eslint: no-ternary

    // ✓ ok
    var foo = isBar ? baz : qux;
  • 禁止使用行尾空白(空格、tab 和其它 Unicode 空白字符)

    eslint: no-trailing-spaces

    // ✓ ok
    var foo = 0;
    var baz = 5;
    
    // ✗ avoid
    var foo = 0;//•••••
    var baz = 5;//••
    //•••••
  • 允许标识符中有悬空下划线

    eslint: no-underscore-dangle

    // ✓ ok
    var foo_;
    var __proto__ = {};
    foo._bar();
  • 当有更简单的结构可以代替三元操作符时,禁止使用三元操作符

    eslint: no-unneeded-ternary

    // ✓ ok
    var a = x === 2 ? "Yes" : "No";
    
    var a = x !== false;
    
    var a = x ? "Yes" : "No";
    
    var a = x ? y : x;
    
    var a = x ? x : 1;
    
    // ✗ avoid
    var a = x === 2 ? true : false;
    
    var a = x ? true : false;
    
    var a = f(x ? x : 1);
  • 禁止属性前有空白

    eslint: no-whitespace-before-property

    // ✓ ok
    foo.bar
    
    foo[bar]
    
    foo
      .bar()
      .baz()
    
    // ✗ avoid
    foo [bar]
    
    foo. bar
    
    foo .bar
    
    foo. bar. baz
    
    foo. bar()
      .baz()
    
    foo
      .bar(). baz()
  • 不限制单行语句的位置

    eslint: nonblock-statement-body-position

    // ✓ ok
    if (foo) {
      bar();
    } else {
      baz();
    }
    
    if (foo) bar();
    else baz();
    
    while (foo) bar();
    
    for (let i = 1; i < foo; i++) bar();
    
    do bar(); while (foo)
    
    // ✓ ok
    if (foo)
      bar();
    else
      baz();
    
    while (foo)
      bar();
    
    for (let i = 1; i < foo; i++)
      bar();
    
    do
      bar();
    while (foo)
  • 如果在属性内部或属性之间有换行符,就要求有换行符

    eslint: object-curly-newline

    // ✓ ok
    let a = {};
    let b = {foo: 1};
    let c = {foo: 1, bar: 2};
    let d = {
        foo: 1,
        bar: 2
    };
    let e = {
        foo: function() {
            dosomething();
        }
    };
    
    let {} = obj;
    let {f} = obj;
    let {g, h} = obj;
    let {
        i,
        j
    } = obj;
    let {
        k = function() {
            dosomething();
        }
    } = obj;
    
    // ✗ avoid
    let a = {
    };
    let b = {
        foo: 1
    };
    let c = {
        foo: 1, bar: 2
    };
    let d = {foo: 1,
        bar: 2};
    let e = {foo: function() {
        dosomething();
    }};
    
    let {
    } = obj;
    let {
        f
    } = obj;
    let {
        g, h
    } = obj;
    let {i,
        j} = obj;
    let {k = function() {
        dosomething();
    }} = obj;
  • 要求每个作用域有多个变量声明

    eslint: one-var

    // ✓ ok
    function foo() {
        var bar;
        var baz;
    }
    
    // ✗ avoid
    function foo(){
        let bar = true,
            baz = false;
    }
  • 不强制每个变量初始化语句换行

    eslint: one-var-declaration-per-line

    // ✓ ok
    var a, b;
    
    let a,
        b;
    
    let a,
        b = 0;
    
    // ✓ ok
    var a, b, c = 0;
    
    let a,
        b = 0, c;
  • 要求尽可能地简化赋值操作

    eslint: operator-assignment

    // ✓ ok
    x += y;
    x = y * z;
    x = (x * y) * z;
    x[0] /= y;
    x[foo()] = x[foo()] % 2;
    x = y + x;
    
    // ✗ avoid
    x = x + y;
    x = y * x;
    x[0] = x[0] / y;
    x.y = x.y << z;
  • 要求把换行符放在操作符前面

    eslint: operator-linebreak

    // ✓ ok
    foo = 1 + 2;
    
    foo = 1
        + 2;
    
    foo
        = 5;
    
    // ✗ avoid
    foo = 1 +
          2;
    
    foo =
        5;
  • 不强制块语句和类的开始或末尾有空行

    eslint: padded-blocks

    // ✓ ok
    if (a) {
        b();
    }
    
    if (a) {
    
        b();
    
    }
    
    if (a) {
        b();
    
    }
  • 不强制在语句间填充空行

    eslint: padding-line-between-statements

    // ✓ ok
    function foo() {
        bar();
    
        return;
    }
    
    // ✓ ok
    function foo() {
        bar();
        return;
    }
  • 按具体需要决定是否对对象字面量属性名称使用引号

    eslint: quote-props

    // ✓ ok
    var object1 = {
        "a-b": 0,
        "0x0": 0,
        "1e2": 0
    };
    
    var object3 = {
        foo() {
            return;
        }
    };
    
    // ✗ avoid
    var object = {
        "a": 0,
        "b": 0,
    };
  • 要求尽可能地使用单引号

    eslint: quotes

    // ✓ ok
    var single = 'single';
    var backtick = `back${x}tick`;
    
    // ✗ avoid
    var double = "double";
    var unescaped = "a string containing 'single' quotes";
  • 不强制使用 JSDoc 注释

    eslint: require-jsdoc

    // ✓ ok
    function foo() {
        return 10;
    }
    
    /**
     * It returns 10
     */
    function foo() {
        return 10;
    }
  • 要求在语句末尾使用分号

    eslint: semi

    // ✓ ok
    var name = "ESLint";
    
    object.method = function() {
        // ...
    };
    
    // ✗ avoid
    var name = "ESLint"
    
    object.method = function() {
        // ...
    }
  • 强制分号之前无空格,分号之后有空格

    eslint: semi-spacing

    // ✓ ok
    var foo;
    var foo; var bar;
    throw new Error("error");
    for (i = 0; i < 10; i++) {}
    
    // ✗ avoid
    var foo ;
    var foo;var bar;
    throw new Error("error") ;
    for (i = 0 ; i < 10 ; i++) {}
    for (i = 0;i < 10;i++) {}
  • 强制分号出现在句子末尾

    eslint: semi-style

    // ✓ ok
    var a = 1;
    var b = 3;
    
    // ✗ avoid
    var a = 1
    ;var b = 2
    ;var c = 3
    ;
  • 不要求对象属性按序排列

    eslint: sort-keys

    // ✓ ok
    let obj = {a: 1, c: 3, b: 2};
    let obj = {a: 1, b: 2, c: 3};
  • 要求同一个声明块中的变量按顺序排列,忽略大小写

    eslint: sort-vars

    // ✓ ok
    var a, b;
    
    var a, A;
    
    var a, B, c;
    
    // ✗ avoid
    var b, a;
    
    var c, a, B;
  • 块语句必须总是至少有一个前置空格

    eslint: space-before-blocks

    // ✓ ok
    if (a) {
        b();
    }
    
    // ✗ avoid
    if (a){
        b();
    }
  • 强制在 function的左括号之前使用空格

    eslint: space-before-function-paren\

    // ✓ ok
    function foo() {
        // ...
    }
    
    // ✗ avoid
    function foo () {
        // ...
    }
  • 强制在圆括号内使用一致的空格

    eslint: space-in-parens

    // ✓ ok
    foo();
    
    foo('bar');
    
    var foo = (1 + 2) * 3;
    (function () { return 'bar'; }());
    
    // ✗ avoid
    foo( 'bar');
    foo('bar' );
    foo( 'bar' );
    
    var foo = ( 1 + 2 ) * 3;
    ( function () { return 'bar'; }() );
  • 中缀运算符周围有空格

    eslint: space-infix-ops

    // ✓ ok
    a + b
    
    // ✗ avoid
    a+b
    
    a+ b
    
    a +b
  • 注释块 // 或 / 必须跟随至少一个空白*

    eslint: spaced-comment

    // ✓ ok
    /* 注释 */
    
    // 注释
    
    /* 注释 */
    
    /*
     * 注释
     */
    
    /*
    注释
    */
    
    // ✗ avoid
    /*注释*/
    
    //注释
  • 要求switch case冒号之后有一个空格

    eslint: switch-colon-spacing

    // ✓ ok
    switch (a) {
        case 0: foo(); break;
        case 1:
            bar();
            break;
        default:
            baz();
            break;
    }
    
    // ✗ avoid
    switch (a) {
        case 0 :break;
        default :foo();
    }
  • 禁止在模板标记和它们的字面量之间有空格

    eslint: template-tag-spacing

    // ✓ ok
    func`Hello world`;
    
    // ✗ avoid
    func `Hello world`;
  • 不要求按 Unicode 字节顺序标记 (BOM)

    eslint: unicode-bom

    // ✓ ok
    U+FEFF
    var abc;
    
    // ✓ ok
    var abc;
  • 不要求正则表达式被括号括起来

    eslint: wrap-regex

    // ✓ ok
    function a() {
        return (/foo/).test("bar");
    }
    
    // ✓ ok
    function a() {
        return /foo/.test("bar");
    }

ECMAScript 6

  • 当箭头函数大括号是可以省略的,强制不使用它们

    eslint: arrow-body-style

    // ✓ ok
    let foo = () => 0;
    let foo = (retv, name) => {
        retv[name] = true;
        return retv;
    };
    
    // ✗ avoid
    let foo = () => {
        return 0;
    };
  • 要求箭头函数在所有情况下使用圆括号将参数括起来

    eslint: arrow-parens

    // ✓ ok
    () => {};
    (a) => {};
    (a) => a;
    (a) => {'\n'}
    
    // ✗ avoid
    a => {};
    a => a;
    a => {'\n'}
  • 规范化箭头函数的箭头(=>)之前或之后的空格

    eslint: arrow-spacing

    // ✓ ok
    () => {};
    (a) => {};
    () => {'\n'};
    
    // ✗ avoid
    () =>{};
    (a) => {};
    ()=> {'\n'};
  • 派生类中的构造函数必须调用 super()。非派生类的构造函数不能调用 super()

    eslint: constructor-super

    // ✓ ok
    class A extends B {
        constructor() {
            super();
        }
    }
    
    // ✗ avoid
    class A {
        constructor() {
            super();
        }
    }
    
    class A extends B {
        constructor() { }
    }
  • 强制在 * 和 function 关键字之间有空格, 之后无空格*

    eslint: generator-star-spacing

    // ✓ ok
    function *generator() {
        yield "44";
        yield "55";
    }
    
    // ✗ avoid
    function * generator() {
        yield "44";
        yield "55";
    }
  • 禁止修改class 声明的变量

    eslint: no-class-assign

    // ✓ ok
    let A = class A { }
    A = 0; // A is a variable.
    
    // ✗ avoid
    A = 0;
    class A { }
  • 禁止在可能与比较操作符相混淆的地方使用箭头函数

    eslint: no-confusing-arrow

    // ✓ ok
    var x = (a) => (1 ? 2 : 3);
    var x = (a) => { return 1 ? 2 : 3; };
    
    // ✗ avoid
    var x = (a) => 1 ? 2 : 3;
    var x = (a) => (1 ? 2 : 3);
  • 禁止修改 const 声明的变量

    eslint: no-const-assign

    // ✓ ok
    const a = 0;
    console.log(a);
    
    // ✗ avoid
    const a = 0;
    ++a;
  • 禁止类成员中出现重复的名称

    eslint: no-dupe-class-members

    // ✓ ok
    class Foo {
      bar() { }
      qux() { }
    }
    
    class Foo {
      get bar() { }
      set bar(value) { }
    }
    
    class Foo {
      static bar() { }
      bar() { }
    }
    
    // ✗ avoid
    class Foo {
      bar() { }
      bar() { }
    }
    
    class Foo {
      bar() { }
      get bar() { }
    }
    
    class Foo {
      static bar() { }
      static bar() { }
    }
  • 禁止重复模块导入

    eslint: no-duplicate-imports

    // ✓ ok
    import { merge, find } from 'module';
    import something from 'another-module';
    
    // ✗ avoid
    import { merge } from 'module';
    import something from 'another-module';
    import { find } from 'module';
  • 禁止在构造函数中,在调用 super() 之前使用 this 或 super

    eslint: no-this-before-super

    // ✓ ok
    class A extends B {
        constructor() {
            super();
            this.a = 0;
        }
    }
    
    // ✗ avoid
    class A extends B {
        constructor() {
            this.foo();
            super();
        }
    }
  • 禁止使用不必要的计算属性

    eslint: no-useless-computed-key

    // ✓ ok
    var c = { 'a': 0 };
    var c = { 0: 0 };
    var a = { x() {} };
    var c = { a: 0 };
    var c = { '0+1,234': 0 };
    
    // ✗ avoid
    var a = { ['0']: 0 };
    var a = { ['0+1,234']: 0 };
    var a = { [0]: 0 };
    var a = { ['x']: 0 };
    var a = { ['x']() {} };
  • 禁止在 import 和 export 和解构赋值时将引用重命名为相同的名字

    eslint: no-useless-rename

    // ✓ ok
    import * as foo from "foo";
    import { foo } from "bar";
    import { foo as bar } from "baz";
    
    export { foo };
    export { foo as bar };
    export { foo as bar } from "foo";
    
    let { foo } = bar;
    let { foo: bar } = baz;
    let { [foo]: foo } = bar;
    
    // ✗ avoid
    import { foo as foo } from "bar";
    export { foo as foo };
    export { foo as foo } from "bar";
    let { foo: foo } = bar;
    let { 'foo': foo } = bar;
  • 阻止 var 的使用,推荐使用 const 或 let

    eslint: no-var

    // ✓ ok
    let x = "y";
    const CONFIG = {};
    
    // ✗ avoid
    var x = "y";
    var CONFIG = {};
  • 不要求对象字面量中方法和属性使用简写语法

    eslint: object-shorthand

    // ✓ ok
    var foo = {
        x: x,
        y: y,
        z: z,
    };
    
    var foo = {
        a: function() {},
        b: function() {}
    };
    
    // ✓ ok
    var foo = {x, y, z};
    
    var foo = {
        a() {},
        b() {}
    };
  • 要求回调函数使用箭头函数

    eslint: prefer-arrow-callback

    // ✓ ok
    foo((a) => a);
    
    // ✗ avoid
    foo(function(a) { return a; });
  • 要求使用 const 声明那些声明后不再被修改的变量

    eslint: prefer-const

    // ✓ ok
    const a = 0;		// 不变的量
    console.log(a);
    
    // ✗ avoid
    let a;			
    a = 0;		// 不再改变
  • 不要求优先使用数组解构和对象解构

    eslint: prefer-destructuring

    // ✓ ok
    var [ foo ] = array;
    var { foo } = object;
    
    // ✓ ok
    var foo = array[someIndex];
    var foo = object.foo;
  • 不禁用 parseInt()Number.parseInt()

    eslint: prefer-numeric-literals

    // ✓ ok
    parseInt("111110111", 2) === 503;
    parseInt("767", 8) === 503;
    parseInt("1F7", 16) === 503;
    Number.parseInt("111110111", 2) === 503;
    Number.parseInt("767", 8) === 503;
    Number.parseInt("1F7", 16) === 503;
    
    // ✓ ok
    0b111110111 === 503;
    0o767 === 503;
    0x1F7 === 503;
  • 要求使用剩余参数而不是 arguments

    eslint: prefer-rest-params

    // ✓ ok
    function foo(...args) {
        console.log(args);
    }
    
    // ✗ avoid
    function foo() {
        console.log(arguments);
    }
  • 要求使用扩展运算符而非 .apply()

    eslint: prefer-spread

    // ✓ ok
    foo(...args);
    
    // ✗ avoid
    foo.apply(null, args);
  • 要求使用模板字面量而非字符串连接

    eslint: prefer-template

    // ✓ ok
    var str = `Hello, ${name}!`;
    var str = `Time: ${12 * 60 * 60 * 1000}`;
    
    // ✗ avoid
    var str = "Hello, " + name + "!";
    var str = "Time: " + (12 * 60 * 60 * 1000);
  • 要求 generator 函数内有 yield

    eslint: require-yield

    // ✓ ok
    function* foo() {
      yield 5;
      return 10;
    }
    
    // ✗ avoid
    function* foo() {
      return 10;
    }
  • 强制剩余和扩展运算符及其表达式之间无空格

    eslint: rest-spread-spacing

    // ✓ ok
    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
    
    // ✗ avoid
    fn(... args)
    [... arr, 4, 5, 6]
  • 不强制模块内的 import 排序

    eslint: sort-imports

    // ✓ ok
    import b from 'foo.js';
    import a from 'bar.js';
    
    // ✓ ok
    import a from 'baz.js';
    import b from 'qux.js';
  • 不要求 symbol 描述

    eslint: symbol-description

    // ✓ ok
    var foo = Symbol("some description");
    
    // ✓ ok
    var foo = Symbol();
  • 禁止模板字符串中的嵌入表达式周围空格的使用

    eslint: template-curly-spacing

    // ✓ ok
    `hello, ${people.name}!`;
    
    `hello, ${
        people.name
    }!`;
    
    // ✗ avoid
    `hello, ${ people.name}!`;
    `hello, ${people.name }!`;
    
    `hello, ${ people.name }!`;
  • 强制在 yield 表达式中 * 之前使用空格*

    eslint: yield-star-spacing

    // ✓ ok
    function *generator() {
      yield *other();
    }
    
    // ✗ avoid
    function *generator() {
      yield* other();
    }

Vue

  • 强制 .vue 文件里的template内缩进为4个空格

    eslint-plugin-vue: vue/html-indent

    <!-- ✓ ok -->
    <template>
        <div class="foo">
          	Hello.
        </div>
    </template>
    
    <!-- ✗ avoid -->
    <template>
    	<div class="foo">
      	Hello.
      </div>
    </template>
  • 强制 .vue 文件里的template内每行最多一个属性

    eslint-plugin-vue: vue/max-attributes-per-line

    <template>
      <!-- ✓ ok -->
      <MyComponent lorem="1"/>
      <MyComponent
        lorem="1"
        ipsum="2"
      />
      <MyComponent
        lorem="1"
        ipsum="2"
        dolor="3"
      />
    
      <!-- ✗ avoid -->
      <MyComponent lorem="1" ipsum="2"/>
      <MyComponent
        lorem="1" ipsum="2"
      />
      <MyComponent
        lorem="1" ipsum="2"
        dolor="3"
      />
    </template>
  • 不要求.vue文件内元素的内容前后断行

    eslint-plugin-vue: vue/singleline-html-element-content-newline

    <template>
      <!-- ✓ ok -->
      <div attr>
        content
      </div>
      
      <tr attr>
        <td>
          {{ data1 }}
        </td>
        <td>
          {{ data2 }}
        </td>
      </tr>
      
      <div attr>
        <!-- comment -->
      </div>
      
      <!-- ✗ ok -->
      <div attr>content</div>
      
      <tr attr><td>{{ data1 }}</td><td>{{ data2 }}</td></tr>
      
      <div attr><!-- comment --></div>
    </template>
  • 要求.vue文件内开始标签和结束标签的结尾符号前没有空格

    eslint-plugin-vue: vue/html-closing-bracket-spacing

    <template>
      <!-- ✓ ok -->
      <div>
      <div foo>
      <div foo="bar">
      </div>
      <div />
      <div foo />
      <div foo="bar" />
    
      <!-- ✗ avoid -->
      <div >
      <div foo >
      <div foo="bar" >
      </div >
      <div/>
      <div foo/>
      <div foo="bar"/>
    </template>
  • 强制组件标签、void标签(img等)、svg标签、math标签自我闭合

    eslint-plugin-vue: vue/html-self-closing

    <template>
      <!-- ✓ ok -->
      <div></div>
      <img/>
      <MyComponent/>
      <svg><path d=""/></svg>
    
      <!-- ✗ avoid -->
      <div/>
      <img>
      <MyComponent></MyComponent>
      <svg><path d=""></path></svg>
    </template>