ESLint の "Rules" における "no-label-var" ルールについて


ESLint の "Rules" における "no-label-var" ルールについて

ESLint の "no-label-var" ルールは、ループやスイッチ文などのラベルと、同じ名前の変数がスコープ内に存在することを禁止するルールです。このルールは、コードの可読性とメンテナンス性を向上させることを目的としています。

問題点

ラベルと変数が同じ名前を持つ場合、コードが読みにくくなり、意図しない動作を引き起こす可能性があります。例えば、以下のコードを見てみましょう。

var i = 0;

loop:
  while (i < 10) {
    i++;

    if (i === 5) {
      break loop;
    }
  }

このコードでは、loop というラベルと i という変数が同じ名前です。この場合、break loop; ステートメントは、loop ラベルではなく、i 変数のループから抜け出す可能性があります。

解決策

この問題を解決するには、ラベルと変数の名前を異なるものにすればよいでしょう。例えば、以下のコードのように変更できます。

var i = 0;

outerLoop:
  while (i < 10) {
    i++;

    if (i === 5) {
      break outerLoop;
    }
  }

no-label-var ルールの設定

no-label-var ルールは、ESLint のデフォルトルールではありません。このルールを有効にするには、.eslintrc ファイルに以下の設定を追加する必要があります。

{
  "rules": {
    "no-label-var": "error"
  }
}

no-label-var ルールは、以下の場合に例外として許可されます。

  • ラベルが default である場合
  • ラベルが case または default である switch 文内にある場合


ラベルと変数が同じ名前の場合

var i = 0;

loop:
  while (i < 10) {
    i++;

    if (i === 5) {
      break loop; // 意図: loop ラベルから抜ける
    }
  }
var i = 0;

outerLoop:
  while (i < 10) {
    i++;

    if (i === 5) {
      break outerLoop; // 正しい: outerLoop ラベルから抜ける
    }
  }

このコードは、no-label-var ルールによって問題ありません。break outerLoop; ステートメントは、意図したとおり outerLoop ラベルから抜け出します。

switch (x) {
  case 1:
    console.log("x is 1");
    break;
  case 2:
    console.log("x is 2");
    break;
  default:
    console.log("x is neither 1 nor 2");
}

このコードは、no-label-var ルールによって問題ありません。ラベル default は、switch 文内で特別な意味を持つため、許可されています。

switch (x) {
  case 1:
    console.log("x is 1");
    break case 1; // 正しい: case 1 ラベルから抜ける
  case 2:
    console.log("x is 2");
    break case 2; // 正しい: case 2 ラベルから抜ける
  default:
    console.log("x is neither 1 nor 2");
}


"no-label-var" の代替方法

しかし、場合によっては "no-label-var" ルールが意図しない動作を引き起こすことがあります。そのような場合は、以下の代替方法を検討することができます。

代替方法

  1. ラベルと変数の名前を変える

これは、最も簡単で確実な代替方法です。ラベルと変数の名前を異なるものにすれば、両者の区別がつきやすくなり、意図しない動作を防ぐことができます。

  1. ラベル付き continue または break ステートメントを使用する

ラベル付き continue または break ステートメントを使用することで、ラベルと変数の名前が同じ場合でも、意図した動作を実現することができます。

var i = 0;

loop:
  while (i < 10) {
    i++;

    if (i === 5) {
      continue loop; // 正しい: loop ラベルから次のイテレーションへ進む
    }
  }
  1. ラベル付き goto ステートメントを使用する
var i = 0;

loop:
  while (i < 10) {
    i++;

    if (i === 5) {
      goto endLoop; // 正しい: endLoop ラベルへジャンプ
    }
  }

endLoop:

注意点

ラベル付き goto ステートメントは、コードの可読性を低下させる可能性があるため、使用には注意が必要です。