# semi
要求或禁止使用分号而不是 ASI
一些该规则报告的问题可以通过 --fix 命令行选项 自动修复
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
字符总是结束一个语句(就像一个分号),除非满足以下条件之一:
# 规则详情
此规则强制使用一致的分号。
# 选项
该规则有两个选项,一个字符串选项和一个对象选项。
字符串选项:
"always"
(默认)在语句末尾需要分号"never"
不允许使用分号作为语句的结尾(除了消除以[
、(
、/
、+
或-
开头的语句的歧义)
对象选项("always"
时):
"omitLastInOneLineBlock": true
忽略块中的最后一个分号,其中它的大括号(以及块的内容)在同一行中
对象选项("never"
时):
- 如果下一行以
[
、(
、/
、+
或-
开头,"beforeStatementContinuationChars": "any"
(默认)忽略语句末尾的分号(或缺少分号)。 - 如果下一行以
[
、(
、/
、+
或-
开头,则"beforeStatementContinuationChars": "always"
需要在语句末尾使用分号。 - 即使下一行以
[
、(
、/
、+
或-
开头,如果"beforeStatementContinuationChars": "never"
不会造成 ASI 危险,则"beforeStatementContinuationChars": "never"
不允许将分号作为语句的结尾。
注意: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;
}
# 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
}
# 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() }
}
# 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() {
// ...
})()
# 何时不使用
如果您不想以任何特定方式强制使用分号(或省略),则可以关闭此规则。