コンテンツへスキップ

@stylistic/js/

semi

JavaScriptでは、ステートメントの最後にセミコロンを付ける必要はありません。多くの場合、JavaScriptエンジンはセミコロンをどこに置くべきかを判断し、自動的に追加します。この機能は**自動セミコロン挿入(ASI)**として知られており、JavaScriptの中でも特に議論の多い機能の一つとされています。例えば、次の2行はどちらも有効です。

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

最初の行では、JavaScriptエンジンが自動的にセミコロンを挿入するため、構文エラーとはみなされません。JavaScriptエンジンは依然としてこの行を解釈する方法を知っており、行末がステートメントの終わりを示していることを理解しています。

ASIに関する議論では、一般的に2つの考え方があります。1つ目は、ASIが存在しないかのように扱い、常に手動でセミコロンを付けるべきという考え方です。その理由は、セミコロンが必要かどうかの記憶に頼るよりも、常にセミコロンを付ける方が簡単であり、エラーの可能性を減らすことができるためです。

しかし、ASIメカニズムは、セミコロンを使用している人にとって、時に厄介な場合があります。例えば、次のコードを考えてみてください。

js
return
{
    name: "ESLint"
};

これはオブジェクトリテラルを返す`return`ステートメントのように見えますが、JavaScriptエンジンはこれを次のように解釈します。

js
return;
{
    name: "ESLint";
}

実際には、`return`ステートメントの後にセミコロンが挿入され、その後のコード(ブロック内のラベル付きリテラル)に到達できなくなります。このルールとno-unreachableルールは、このような場合にコードを保護します。

一方、セミコロンは自動的に挿入されるため、オプションであり、手動で挿入する必要はないと主張する人もいます。しかし、ASIメカニズムは、セミコロンを使用しない人にとっても、時に厄介な場合があります。例えば、次のコードを考えてみてください。

js
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()`、`do`、`if()`、または`else`であり、`{`がありません。
  4. 次の行は`[`、`(`、`+`、`*`、`/`、`-`、`,`、`.`、または単一式内の2つのトークンの間でのみ見つかる他の2項演算子で始まります。

ルール詳細

このルールは、セミコロンの一貫した使用を強制します。

オプション

このルールには、文字列オプションとオブジェクトオプションの2つのオプションがあります。

文字列オプション

  • `"always"`(デフォルト)は、ステートメントの最後にセミコロンを付けることを要求します。
  • `"never"`は、ステートメントの最後にセミコロンを付けることを禁止します(`[`、`(`、`/`、`+`、または`-`で始まるステートメントのあいまいさを解消する場合を除く)。

オブジェクトオプション(`always`の場合)

  • `"omitLastInOneLineBlock": true`は、その中括弧(およびブロックの内容)が同じ行にあるブロックの最後のセミコロンを禁止します。
  • `"omitLastInOneLineClassBody": true`は、その中括弧(およびクラスボディの内容)が同じ行にあるクラスボディの最後のセミコロンを禁止します。

オブジェクトオプション(`never`の場合)

  • `"beforeStatementContinuationChars": "any"`(デフォルト)は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、ステートメントの末尾のセミコロン(またはセミコロンがないこと)を無視します。
  • `"beforeStatementContinuationChars": "always"`は、次の行が`[`、`(`、`/`、`+`、または`-`で始まる場合、ステートメントの最後にセミコロンを付けることを要求します。
  • `"beforeStatementContinuationChars": "never"`は、次の行が`[`、`(`、`/`、`+`、または`-`で始まったとしても、ASIの危険性を生じさせない場合、ステートメントの末尾のセミコロンを禁止します。

**注記:** `beforeStatementContinuationChars`は、クラスフィールドには適用されません。クラスフィールドはステートメントではないためです。

always

デフォルトの`"always"`オプションを使用したこのルールに対する**不正な**コードの例

js
/*eslint @stylistic/js/semi: ["error", "always"]*/

var name = "ESLint"
object.method = function() { // ... }
class Foo { bar = 1
}
incorrect

デフォルトの`"always"`オプションを使用したこのルールに対する**正しい**コードの例

js
/*eslint @stylistic/js/semi: "error"*/

var name = "ESLint";

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

class Foo {
    bar = 1;
}
correct

omitLastInOneLineBlock

`"always", { "omitLastInOneLineBlock": true }`オプションを使用したこのルールに対する追加の**正しい**コードの例

js
/*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() }
}
correct

omitLastInOneLineClassBody

`"always", { "omitLastInOneLineClassBody": true }`オプションを使用したこのルールに対する追加の**正しい**コードの例

js
/*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}
correct

never

`"never"`オプションを使用したこのルールに対する**不正な**コードの例

js
/*eslint @stylistic/js/semi: ["error", "never"]*/

var name = "ESLint"
;
object.method = function() { // ... }
;
class Foo { bar = 1
;
}
incorrect

`"never"`オプションを使用したこのルールに対する**正しい**コードの例

js
/*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
}
correct

beforeStatementContinuationChars

`"never", { "beforeStatementContinuationChars": "always" }`オプションを使用したこのルールに対する追加の**不正な**コードの例

js
/*eslint @stylistic/js/semi: ["error", "never", { "beforeStatementContinuationChars": "always"}] */
import a from "a"
(function() { // ... })()
incorrect

`"never", { "beforeStatementContinuationChars": "never" }`オプションを使用したこのルールに対する追加の**不正な**コードの例

js
/*eslint @stylistic/js/semi: ["error", "never", { "beforeStatementContinuationChars": "never"}] */
import a from "a"

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

使用しない場合

特定の方法でセミコロンの使用(または省略)を強制したくない場合は、このルールをオフにすることができます。

MITライセンスの下で公開されています。