JavaScript エラー
1. エラーは必ず発生する!
JavaScriptコードを実行する際、さまざまなエラーが発生する可能性があります。
エラーの原因には、プログラマーによるコーディングミス、不正なインプット(入力値)、あるいはその他の予期せぬ事象が含まれます。
- ReferenceError(参照エラー)
- TypeError(型エラー)
- RangeError(範囲エラー)
- URIError(URIエラー)
- SyntaxError(構文エラー)
- EvalError(評価エラー:現在は非推奨)
- Silent Error(サイレントエラー:次章で解説)
2. JavaScriptエラーのハンドリング方法
try ステートメントを使用すると、コードの実行中にエラーが発生するかどうかをテストするブロックを定義できます。catch ステートメントを使用すると、try ブロックでエラーが発生した場合に実行されるコードブロックを定義できます。
JavaScriptの try と catch は必ずペアで使用します:
try {
// テストするコードブロック
} catch(err) {
// エラーを処理するコードブロック
}3. ReferenceError(参照エラー)
ReferenceError は、存在しない変数を「参照(使用)」した場合に発生します。
| エラータイプ | 例 | エラーメッセージ |
|---|---|---|
| ReferenceError | fname = foo; | foo is not defined |
| ReferenceError | let 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 は、値が許容される有効な範囲外である場合に発生します。
| エラータイプ | 例 | エラーメッセージ |
|---|---|---|
| RangeError | new Array(-1); | Invalid array length |
| RangeError | num.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)操作関数において不正な文字が使用された場合に発生します。
| エラータイプ | 例 | エラーメッセージ |
|---|---|---|
| URIError | decodeURI("%%%"); | URI malformed |
6.1 使用例
try {
// パーセント記号のみの文字列はデコードできない
decodeURI("%%%");
} catch(err) {
document.getElementById("demo").innerHTML = err.name;
}7. SyntaxError(構文エラー)
SyntaxError は、コードが JavaScript の文法ルールに違反している場合に発生します。
| 例 | エラー名 | エラー内容 |
|---|---|---|
fname = "John); | SyntaxError | Invalid or unexpected token |
Math.round(4.6; | SyntaxError | Missing ) 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 なぜキャッチできないのか
ブラウザがスクリプトを処理する際、以下のステップを踏みます:
- JavaScript エンジンがスクリプトを実行する前に SyntaxError をスローします。
- 構文エラーは
try...catchブロックが実行されるよりも前に検知されます。 - つまり、
tryブロックが開始されることすらありません。スクリプト自体の実行が失敗します。
ブラウザのコンソール(F12 → Console タブ)には、Uncaught SyntaxError: missing ) after argument list のようなエラーが表示されます。
8. EvalError(評価エラー)
EvalError は、eval() 関数内でのエラーを示します。
ただし、現在の新しいバージョンの JavaScript では EvalError をスローしません。代わりに SyntaxError が使用されます。