semi
需要或不允许使用分号代替ASI(semi)
在--fix
命令行上的选项可以自动修复一些被这条规则反映的问题。
JavaScript在类似C语言中是独一无二的,因为它在每个语句的末尾都不需要分号。在很多情况下,JavaScript引擎可以确定分号应该位于某个位置,并自动添加它。这个特性被称为自动分号插入(ASI)
,被认为是JavaScript中比较有争议的特性之一。例如,以下几行都是有效的:
var name = "ESLint"
var website = "eslint.org";
在第一行中,JavaScript引擎会自动插入一个分号,所以这不被视为语法错误。JavaScript引擎仍然知道如何解释该行,并知道行结束表示语句的结尾。
在关于ASI的辩论中,通常有两种思想流派。首先是我们应该把ASI当作不存在,并且总是手动包含分号。其基本原理是总是包含分号比试图记住它们是否被要求更容易,从而减少引入错误的可能性。
但是,对于使用分号的人来说,ASI机制有时会非常棘手。例如,请考虑以下代码:
return
{
name: "ESLint"
};
这可能看起来像一个return
返回对象字面值的语句,但是,JavaScript引擎会将此代码解释为:
return;
{
name: "ESLint";
}
实际上,在return
语句之后插入分号,导致其下面的代码(块内的标记文字)无法访问。这个规则和不可达规则将保护你的代码免受这种情况的影响。
另一方面,那些说自动插入分号的人是可选的,不需要手动插入。但是,对于不使用分号的人来说,ASI机制也会非常棘手。例如,请考虑以下代码:
var globalCounter = { }
(function () {
var n = 0
globalCounter.increment = function () {
return ++n
}
})()
在这个例子中,第一行后面不会插入分号,导致运行时错误(因为空对象被称为函数)。没有意外的多行规则可以保护你的代码免受这种情况的影响。
尽管ASI允许您在编码风格上拥有更多的自由,但它也可以让您的代码以意想不到的方式行事,不管您是否使用分号。因此,最好知道ASI何时发生,何时不发生,并让ESLint保护您的代码免受这些潜在意外情况的影响。简而言之,正如Isaac Schlueter所描述的那样,\n
除非满足以下条件之一,否则角色总是结束语句(就像分号一样):
- 该语句具有未关闭的paren,数组字面量或对象字面量,或以其他方式结束,这不是结束语句的有效方式。(例如,以
.
或,
结尾)
2. 该行是--
或++
(在这种情况下,它会减少/增加下一个标记。)
3. 这是一个for()
,while()
,do
,if()
,或else
,并没有{
4.
下一行开头[
,(
,+
,*
,/
,-
,,
,.
,或只能在两个标记之间在一个表达式中找到一些其他二进制运算符。
规则细节
此规则强制使用分号。
选项
该规则有两个选项,一个字符串选项和一个对象选项。
字符串选项:
"always"
(default)在语句结尾需要分号
"never"
不允许分号语句的末尾(除非消除歧义开头语句[
,(
,/
,+
,或-
)
对象选项(何时"always"
):
"omitLastInOneLineBlock": true
忽略其大括号(因此块的内容)在同一个lineObject选项(当"never"
)中的块中的最后一个分号:
"beforeStatementContinuationChars": "any"
(默认)忽略在声明的末尾分号(或缺乏分号),如果下一行开头[
,(
,/
,+
,或-
。
"beforeStatementContinuationChars": "always"
要求在声明的末尾分号,如果下一行开头[
,(
,/
,+
,或-
。
"beforeStatementContinuationChars": "never"
不允许分号语句结束时,如果它没有ASI危险,即使下一行开头[
,(
,/
,+
,或-
。
always
此规则的默认代码错误
代码示例"always"
:
/*eslint semi: ["error", "always"]*/
var name = "ESLint"
object.method = function() {
// ...
}
具有默认选项的此规则的正确
代码示例"always"
:
/*eslint semi: "error"*/
var name = "ESLint";
object.method = function() {
// ...
};
never
此规则的错误
代码示例包含以下"never"
选项:
/*eslint semi: ["error", "never"]*/
var name = "ESLint";
object.method = function() {
// ...
};
此规则的正确
代码示例包含以下"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() {
// ...
})()
omitLastInOneLineBlock
此规则的附加正确
代码示例包含以下"always", { "omitLastInOneLineBlock": true }
选项:
/*eslint semi: ["error", "always", { "omitLastInOneLineBlock": true}] */
if (foo) { bar() }
if (foo) { 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() {
// ...
})()
何时不使用它
如果您不想以任何特定方式强制使用分号(或省略),则可以关闭此规则。
进一步阅读
相关规则
- no-extra-semi
- no-unexpected-multiline
- semi-spacing
版本
这条规则是在ESLint 0.0.6中引入的。