semi
JavaScriptでは、ステートメントの最後にセミコロンを付ける必要はありません。多くの場合、JavaScriptエンジンはセミコロンをどこに置くべきかを判断し、自動的に追加します。この機能は**自動セミコロン挿入(ASI)**として知られており、JavaScriptの中でも特に議論の多い機能の一つとされています。例えば、次の2行はどちらも有効です。
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項演算子で始まります。
ルール詳細
このルールは、セミコロンの一貫した使用を強制します。
オプション
このルールには、文字列オプションとオブジェクトオプションの2つのオプションがあります。
文字列オプション
- `"always"`(デフォルト)は、ステートメントの最後にセミコロンを付けることを要求します。
- `"never"`は、ステートメントの最後にセミコロンを付けることを禁止します(`[`、`(`、`/`、`+`、または`-`で始まるステートメントのあいまいさを解消する場合を除く)。
オブジェクトオプション(`always`の場合)
- `"omitLastInOneLineBlock": true`は、その中括弧(およびブロックの内容)が同じ行にあるブロックの最後のセミコロンを禁止します。
- `"omitLastInOneLineClassBody": true`は、その中括弧(およびクラスボディの内容)が同じ行にあるクラスボディの最後のセミコロンを禁止します。
オブジェクトオプション(`never`の場合)
- `"beforeStatementContinuationChars": "any"`(デフォルト)は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、ステートメントの末尾のセミコロン(またはセミコロンがないこと)を無視します。
- `"beforeStatementContinuationChars": "always"`は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、ステートメントの最後にセミコロンを付けることを要求します。
- `"beforeStatementContinuationChars": "never"`は、次の行が`[`、`(`、`/`、`+`、または`-`で始まったとしても、ASIの危険性を生じさせない場合、ステートメントの末尾のセミコロンを禁止します。
**注記:** `beforeStatementContinuationChars`は、クラスフィールドには適用されません。クラスフィールドはステートメントではないためです。
always
デフォルトの`"always"`オプションを使用したこのルールに対する**不正な**コードの例
/*eslint @stylistic/js/semi: ["error", "always"]*/
var name = "ESLint"
object.method = function() {
// ...
}
class Foo {
bar = 1
}
デフォルトの`"always"`オプションを使用したこのルールに対する**正しい**コードの例
/*eslint @stylistic/js/semi: "error"*/
var name = "ESLint";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
omitLastInOneLineBlock
`"always", { "omitLastInOneLineBlock": true }`オプションを使用したこのルールに対する追加の**正しい**コードの例
/*eslint @stylistic/js/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/js/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/js/semi: ["error", "never"]*/
var name = "ESLint";
object.method = function() {
// ...
};
class Foo {
bar = 1;
}
`"never"`オプションを使用したこのルールに対する**正しい**コードの例
/*eslint @stylistic/js/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/js/semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
import a from "a"
(function() {
// ...
})()
`"never", { "beforeStatementContinuationChars": "never" }`オプションを使用したこのルールに対する追加の**不正な**コードの例
/*eslint @stylistic/js/semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
import a from "a"
;(function() {
// ...
})()
使用しない場合
特定の方法でセミコロンの使用(または省略)を強制したくない場合は、このルールをオフにすることができます。