版本

semi

要求或禁止使用分号而不是 ASI

🔧 可修复

此规则报告的一些问题可以通过 --fix 命令行 选项自动修复。

此规则已在 ESLint v8.53.0 中**弃用**。请在 相应的规则 中使用 @stylistic/eslint-plugin-js

JavaScript 不要求在每个语句的末尾使用分号。在许多情况下,JavaScript 引擎可以确定分号应该出现在某个位置,并会自动添加它。此功能称为**自动分号插入 (ASI)**,被认为是 JavaScript 中更有争议的功能之一。例如,以下两行都是有效的

var name = "ESLint"
var website = "eslint.org";

在第一行中,JavaScript 引擎将自动插入分号,因此这不会被视为语法错误。JavaScript 引擎仍然知道如何解释该行,并且知道行尾表示语句的结束。

在关于 ASI 的争论中,通常有两种观点。第一种观点是,我们应该将 ASI 视为不存在,并始终手动包含分号。其理由是,始终包含分号比尝试记住何时需要或不需要分号更容易,从而降低了引入错误的可能性。

但是,ASI 机制有时会让人们在使用分号时感到棘手。例如,考虑以下代码

return
{
    name: "ESLint"
};

这可能看起来像一个返回对象字面量的 return 语句,但是,JavaScript 引擎会将此代码解释为

return;
{
    name: "ESLint";
}

实际上,在 return 语句之后插入了一个分号,导致其下面的代码(块内带标签的字面量)无法访问。此规则和 no-unreachable 规则将保护您的代码免受此类情况的影响。

另一方面,有些人认为,由于分号是自动插入的,因此它们是可选的,不需要手动插入。但是,ASI 机制对于不使用分号的人来说也可能很棘手。例如,考虑以下代码

var globalCounter = { }

(function () {
    var n = 0
    globalCounter.increment = function () {
        return ++n
    }
})()

在此示例中,在第一行之后不会插入分号,从而导致运行时错误(因为空对象被调用,就好像它是一个函数一样)。no-unexpected-multiline 规则可以保护您的代码免受此类情况的影响。

尽管 ASI 允许您在编码风格方面拥有更大的自由度,但它也可能导致您的代码以意想不到的方式运行,无论您是否使用分号。因此,最好了解 ASI 何时发生以及何时不发生,并让 ESLint 保护您的代码免受这些潜在的意外情况的影响。简而言之,正如 Isaac Schlueter 曾经描述的那样,\n 字符始终结束一个语句(就像分号一样),除非以下情况之一为真

  1. 该语句具有未关闭的括号、数组字面量或对象字面量,或者以某种不是有效结束语句的方式结束。(例如,以 ., 结束。)
  2. 该行为 --++(在这种情况下,它将递减/递增下一个标记。)
  3. 它是 for()while()doif()else,并且没有 {
  4. 下一行以 [(+*/-,. 或其他只能在单个表达式中的两个标记之间找到的二元运算符开头。

规则详情

此规则强制执行分号的一致使用。

选项

此规则有两个选项,一个字符串选项和一个对象选项。

字符串选项

  • "always"(默认)要求在语句末尾使用分号
  • "never" 禁止在语句末尾使用分号(除非用于消除以 [(/+- 开头的语句的歧义)

对象选项(当 "always" 时)

  • "omitLastInOneLineBlock": true 禁止其大括号(以及块的内容)在同一行中的块中的最后一个分号
  • "omitLastInOneLineClassBody": true 禁止其大括号(以及类体的内容)在同一行中的类体中的最后一个分号

对象选项(当 "never" 时)

  • "beforeStatementContinuationChars": "any"(默认)如果下一行以 [(/+- 开头,则忽略语句末尾的分号(或缺少分号)。
  • "beforeStatementContinuationChars": "always" 如果下一行以 [(/+- 开头,则要求在语句末尾使用分号。
  • "beforeStatementContinuationChars": "never" 禁止在语句末尾使用分号,即使下一行以 [(/+- 开头,也不允许,除非这样做会造成 ASI 危险。

注意:beforeStatementContinuationChars 不适用于类字段,因为类字段不是语句。

always

使用默认 "always" 选项时,此规则的错误代码示例

在在线运行中打开
/*eslint semi: ["error", "always"]*/

var name = "ESLint"

object.method = function() {
    // ...
}

class Foo {
    bar = 1
}

使用默认 "always" 选项时,此规则的正确代码示例

在在线运行中打开
/*eslint semi: "error"*/

var name = "ESLint";

object.method = function() {
    // ...
};

class Foo {
    bar = 1;
}

omitLastInOneLineBlock

使用 "always", { "omitLastInOneLineBlock": true } 选项时,此规则的其他正确代码示例

在在线运行中打开
/*eslint semi: ["error", "always", { "omitLastInOneLineBlock": true}] */

if (foo) { bar() }

if (foo) { bar(); baz() }

function f() { bar(); baz() }

class C {
    foo() { bar(); baz() }

    static { bar(); baz() }
}

omitLastInOneLineClassBody

使用 "always", { "omitLastInOneLineClassBody": true } 选项时,此规则的其他正确代码示例

在在线运行中打开
/*eslint semi: ["error", "always", { "omitLastInOneLineClassBody": true}] */

export class SomeClass{
    logType(){
        console.log(this.type);
        console.log(this.anotherType);
    }
}

export class Variant1 extends SomeClass{type=1}
export class Variant2 extends SomeClass{type=2; anotherType=3}

never

使用 "never" 选项时,此规则的错误代码示例

在在线运行中打开
/*eslint semi: ["error", "never"]*/

var name = "ESLint";

object.method = function() {
    // ...
};

class Foo {
    bar = 1;
}

使用 "never" 选项时,此规则的正确代码示例

在在线运行中打开
/*eslint semi: ["error", "never"]*/

var name = "ESLint"

object.method = function() {
    // ...
}

var name = "ESLint"

;(function() {
    // ...
})()

import a from "a"
(function() {
    // ...
})()

import b from "b"
;(function() {
    // ...
})()

class Foo {
    bar = 1
}

beforeStatementContinuationChars

使用 "never", { "beforeStatementContinuationChars": "always" } 选项时,此规则的其他错误代码示例

在在线运行中打开
/*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
import a from "a"

(function() {
    // ...
})()

使用 "never", { "beforeStatementContinuationChars": "never" } 选项时,此规则的其他错误代码示例

在在线运行中打开
/*eslint semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
import a from "a"

;(function() {
    // ...
})()

何时不使用它

如果您不想以任何特定方式强制执行分号的使用(或省略),则可以关闭此规则。

版本

此规则是在 ESLint v0.0.6 中引入的。

进一步阅读

资源

更改语言