semi
JavaScriptでは、各文の最後にセミコロンを付ける必要はありません。多くの場合、JavaScriptエンジンはセミコロンを特定の位置に配置すべきであると判断し、自動的に追加します。この機能は**自動セミコロン挿入(ASI)**として知られており、JavaScriptのより物議を醸す機能の1つと考えられています。例えば、次の行はどちらも有効です。
var name = "ESLint"
var website = "eslint.org";
最初の行では、JavaScriptエンジンは自動的にセミコロンを挿入するため、これは構文エラーとは見なされません。JavaScriptエンジンは依然として行を解釈する方法を知っており、行末が文の終わりを示していることを認識しています。
ASIに関する議論では、一般的に2つの考え方があります。1つは、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`文字は(セミコロンと同様に)常に文を終了します。ただし、次のいずれかが当てはまる場合を除きます。
- 文に閉じられていない括弧、配列リテラル、またはオブジェクトリテラルが含まれているか、または文を終了する有効な方法ではない他の方法で終了します。(例えば、`.`または`,`で終わる場合)
- 行が`--`または`++`です(この場合、次のトークンをデクリメント/インクリメントします)。
- `for()`、`while()`、`do`、`if()`、または`else`であり、`{`がありません。
- 次の行が`[`、`(`、`+`、`*`、`/`、`-`、`,`、`.`、または単一の式内の2つのトークンの間でのみ見つかるその他の二項演算子で始まります。
ルール詳細
このルールは、セミコロンの一貫した使用を強制します。
オプション
このルールには、文字列オプションとオブジェクトオプションの2つのオプションがあります。
文字列オプション
"always"
(デフォルト)は、文の最後にセミコロンを要求します。"never"
は、文の最後にセミコロンを許可しません(`[`、`(`、`/`、`+`、または`-`で始まる文を明確にする場合を除く)。
オブジェクトオプション("always"
の場合)
"omitLastInOneLineBlock": true
は、その中括弧(したがってブロックの内容)が同じ行にあるブロックの最後のセミコロンを許可しません。"omitLastInOneLineClassBody": true
は、その中括弧(したがってクラスボディの内容)が同じ行にあるクラスボディの最後のセミコロンを許可しません。
オブジェクトオプション("never"
の場合)
"beforeStatementContinuationChars": "any"
(デフォルト)は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、文の最後にあるセミコロン(またはセミコロンがないこと)を無視します。"beforeStatementContinuationChars": "always"
は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、文の最後にセミコロンを要求します。"beforeStatementContinuationChars": "never"
は、次の行が`[`、`(`、`/`、`+`、または`-`で始まったとしても、ASIの危険性がない場合は、文の最後にセミコロンを許可しません。
**注記:**beforeStatementContinuationChars
は、クラスフィールドは文ではないため、クラスフィールドには適用されません。
always
デフォルトの"always"
オプションを使用した場合の、このルールに違反するコードの例
/*eslint @stylistic/semi: ["error", "always"]*/
var name = "ESLint"
object.method = function() {
// ...
}
class Foo {
bar = 1
}
デフォルトの"always"
オプションを使用した場合の、このルールに準拠するコードの例
/*eslint @stylistic/semi: "error"*/
var name = "ESLint";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
omitLastInOneLineBlock
"always", { "omitLastInOneLineBlock": true }
オプションを使用したこのルールに準拠する追加のコードの例
/*eslint @stylistic/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 @stylistic/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 @stylistic/semi: ["error", "never"]*/
var name = "ESLint";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
"never"
オプションを使用したこのルールに準拠するコードの例
/*eslint @stylistic/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 @stylistic/semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
import a from "a"
(function() {
// ...
})()
"never", { "beforeStatementContinuationChars": "never" }
オプションを使用したこのルールに違反する追加のコードの例
/*eslint @stylistic/semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
import a from "a"
;(function() {
// ...
})()
使用しない場合
特定の方法でセミコロンの使用(または省略)を強制したくない場合は、このルールをオフにすることができます。
TypeScript固有
ts/semi
@stylistic/ts/member-delimiter-style
ルールも参照してください。これにより、`type`と`interface`メンバのデリミタを指定できます。