JavaScript 速習チュートリアル

JavaScript エラー

1. エラーは必ず発生する!

JavaScriptコードを実行する際、さまざまなエラーが発生する可能性があります。
エラーの原因には、プログラマーによるコーディングミス、不正なインプット(入力値)、あるいはその他の予期せぬ事象が含まれます。

  • ReferenceError(参照エラー)
  • TypeError(型エラー)
  • RangeError(範囲エラー)
  • URIError(URIエラー)
  • SyntaxError(構文エラー)
  • EvalError(評価エラー:現在は非推奨)
  • Silent Error(サイレントエラー:次章で解説)

2. JavaScriptエラーのハンドリング方法

try ステートメントを使用すると、コードの実行中にエラーが発生するかどうかをテストするブロックを定義できます。
catch ステートメントを使用すると、try ブロックでエラーが発生した場合に実行されるコードブロックを定義できます。

JavaScriptの trycatch は必ずペアで使用します:

try {
  // テストするコードブロック
} catch(err) {
  // エラーを処理するコードブロック
}

3. ReferenceError(参照エラー)

ReferenceError は、存在しない変数を「参照(使用)」した場合に発生します。

エラータイプエラーメッセージ
ReferenceErrorfname = foo;foo is not defined
ReferenceErrorlet x = y; let y = 5;Cannot access y before initialization

3.1 使用例

存在しない変数を使用することはできません:

let x = 5;

try {
  // 変数 y は定義されていないためエラーが発生
  x = y + 1;
} catch(err) {
  // エラー名(ReferenceError)を取得
  let text = err.name;
}

変数の初期化前にアクセスすることもできません:

try {
  // y が宣言(let)される前に y を参照しているためエラー
  let x = y;
  let y = 5;
} catch(err) {
  let text = err.name;
}

4. TypeError(型エラー)

TypeError は、値の型が期待されるものと異なる場合や、その型に対して無効なオペレーションを実行しようとした場合に発生します。

エラーの例エラーメッセージ
let anna = 5; anna(5);anna is not a function
let num = 1; num.toUpperCase();num.toUpperCase is not a function

4.1 使用例

anna() は関数ではありません:

let anna = 5;
try {
  // 数値である anna を関数として呼び出そうとしている
  anna(5);
} catch(err) {
  let text = err.name;
}

数値(Number)を大文字(Upper case)に変換することはできません:

let num = 1;
try {
  // 文字列メソッドである toUpperCase は数値には存在しない
  num.toUpperCase();
} catch(err) {
  let text = err.name;
}

5. RangeError(範囲エラー)

RangeError は、値が許容される有効な範囲外である場合に発生します。

エラータイプエラーメッセージ
RangeErrornew Array(-1);Invalid array length
RangeErrornum.toPrecision(500);toPrecision() argument must be between 1 and 100

5.1 使用例

配列の要素数にマイナスの値を設定することはできません:

try {
  // 配列の長さとして -1 は無効
  new Array(-1);
} catch(err) {
  let text = err.name;
}

数値の有効桁数を 500 に設定することはできません:

let num = 1;

try {
  // toPrecision に指定できる引数の範囲を超えている
  num.toPrecision(500); 
} catch(err) {
  let text = err.name;
}

6. URIError(URIエラー)

URIError は、URI(Uniform Resource Identifier)操作関数において不正な文字が使用された場合に発生します。

エラータイプエラーメッセージ
URIErrordecodeURI("%%%");URI malformed

6.1 使用例

try {
  // パーセント記号のみの文字列はデコードできない
  decodeURI("%%%");
} catch(err) {
  document.getElementById("demo").innerHTML = err.name;
}

7. SyntaxError(構文エラー)

SyntaxError は、コードが JavaScript の文法ルールに違反している場合に発生します。

エラー名エラー内容
fname = "John);SyntaxErrorInvalid or unexpected token
Math.round(4.6;SyntaxErrorMissing ) after argument list

7.1 使用例

この例では、文字列の閉じクォートを忘れるミスをしています:

// この行は JavaScript エンジンがパース(解析)できません
let fName = "John);

// ここで実行が停止します

上記のステートメントは Invalid or unexpected token というエラーを生成し、プログラムの実行は停止します。

7.2 SyntaxError は catch できない

重要な点として、SyntaxError は try...catch でキャッチすることができません。
なぜなら、構文エラーはコードの「実行時(ランタイム)」ではなく、実行前の「パース時」に発生するからです。

失敗する例:
以下のコードはエラーをキャッチしようとしていますが、実際には動作しません。

try {
  // カッコの中に余分なセミコロンがあるため文法エラー
  let x = Math.round(4.6;)
} catch(err) {
  // ここには到達しません
  let text = err.name + " " + err.description;
}

7.3 なぜキャッチできないのか

ブラウザがスクリプトを処理する際、以下のステップを踏みます:

  1. JavaScript エンジンがスクリプトを実行する前に SyntaxError をスローします。
  2. 構文エラーは try...catch ブロックが実行されるよりも前に検知されます。
  3. つまり、try ブロックが開始されることすらありません。スクリプト自体の実行が失敗します。

ブラウザのコンソール(F12 → Console タブ)には、Uncaught SyntaxError: missing ) after argument list のようなエラーが表示されます。

8. EvalError(評価エラー)

EvalError は、eval() 関数内でのエラーを示します。
ただし、現在の新しいバージョンの JavaScript では EvalError をスローしません。代わりに SyntaxError が使用されます。