GitBookjs-primer例外処理この章ではJavaScriptにおける例外処理について学びます。try...catch構文try...catch構文は例外が発生しうるブロックをマークし、例外が発生したときの処理を記述するための構文です。try...catch構文のtryブロック内で例外が発生すると、tryブロック内のそれ以降の処理は実行されず、catch節に処理が移行します。catch節は、tryブロック内で例外が発生すると、発生したエラーオブジェクトとともに呼び出されます。finally節は、tryブロック内で例外が発生したかどうかには関係なく、必ずtry文の最後に実行されます。次のコードでは、tryブロックで例外が発生し、catch節の処理が実行され、最後にfinally節の処理が実行されます。console.log("finally節:この行は実行されます");}また、catch節とfinally節のうち、片方が存在していれば、もう片方の節は省略できます。finally節のみを書いた場合は例外がキャッチされないため、finally節を実行後に例外が発生します。finally節のみでは例外がキャッチされないため、この行は実行されませんthrow文throw文を使うとユーザーが例外を投げることができます。例外として投げられたオブジェクトは、catch節で関数の引数のようにアクセスできます。catch節でオブジェクトを参照できる識別子を例外識別子と呼びます。次のコードでは、catch節のerror識別子でキャッチしたエラーオブジェクトを参照しています。"例外が投げられました"}エラーオブジェクトthrow文ではエラーオブジェクトを例外として投げることができます。ここでは、throw文で例外として投げられるエラーオブジェクトについて見ていきます。ErrorErrorオブジェクトのインスタンスはErrorをnewして作成します。コンストラクタの第一引数には、エラーメッセージとなる文字列を渡します。渡したエラーメッセージはError#messageプロパティに格納されます。次のコードでは、assertPositiveNumber関数でエラーオブジェクトを作成し、例外としてthrowしています。投げられたオブジェクトは、catch節の例外識別子(error)からエラーオブジェクトを取得でき、エラーメッセージが確認できます。positive."}throw文はあらゆるオブジェクトを例外として投げられますが、基本的にErrorオブジェクトのインスタンスを投げることを推奨します。その理由は後述するスタックトレースのためです。Errorオブジェクトはインスタンスの作成時に、そのインスタンスが作成されたファイル名や行数などのデバッグに役立つ情報を持っています。文字列のようなErrorオブジェクトではないオブジェクトを投げてしまうと、スタックトレースが得られません。そのため、次のようにthrow文でErrorオブジェクトではないものを投げるのは非推奨です。"例外が投げられました"}ビルトインエラーエラーには状況に合わせたいくつかの種類があり、これらはビルトインエラーとして定義されています。ビルトインエラーとは、ECMAScript仕様や実行環境に組み込みで定義されているエラーオブジェクトです。ビルトインエラーとして投げられるエラーオブジェクトは、すべてErrorオブジェクトを継承したオブジェクトのインスタンスです。そのため、ユーザーが定義したエラーと同じように例外処理できます。ビルトインエラーにはいくつか種類がありますが、ここでは代表的なものを紹介します。ReferenceErrorReferenceErrorは存在しない変数や関数などの識別子が参照された場合のエラーです。次のコードでは、存在しない変数を参照しているためReferenceError例外が投げられます。エラーメッセージが表示される}SyntaxErrorSyntaxErrorは構文的に不正なコードを解釈しようとした場合のエラーです。基本的にSyntaxError例外は、JavaScriptを実行する前のパース段階で発生します。そのため、実行前に発生する例外であるSyntaxErrorをtry...catch文ではcatchできません。bar!次のコードでは、eval関数を使って実行時にSyntaxErrorを発生させています。eval関数は渡した文字列をJavaScriptとして実行する関数です。実行時に発生したSyntaxErrorは、try...catch文でもcatchできます。エラーメッセージが表示される}TypeErrorTypeErrorは値が期待される型ではない場合のエラーです。次のコードでは、関数ではないオブジェクトを関数呼び出ししているため、TypeError例外が投げられます。エラーメッセージが表示される}ビルトインエラーを投げるビルトインエラーのインスタンスを作成し、そのインスタンスを例外として投げることもできます。通常のErrorオブジェクトと同じように、それぞれのビルトインエラーオブジェクトをnewしてインスタンスを作成できます。関数の引数を文字列に限定したい場合は、次のようにTypeError例外を投げるとよいでしょう。メッセージを確認しなくても、エラーの名前だけで型に関する例外だとすぐにわかります。string"}エラーとデバッグJavaScript開発においてデバッグ中に発生したエラーを理解することは非常に重要です。エラーが持つ情報を活用することで、ソースコードのどこでどのような例外が投げられたのかを知ることができます。エラーはすべてErrorオブジェクトを拡張したオブジェクトで宣言されています。エラーの名前を表すnameプロパティと内容を表すmessageプロパティを持っています。この2つのプロパティを確認することで、多くの場面で開発の助けとなるでしょう。次のコードでは、try...catch文で囲っていない部分で例外が発生しています。x++;}fn();このスクリプトを読み込むと、投げられた例外についてのログがコンソールに出力されます。ここではFirefoxにおける実行例を示します。このエラーログには次の情報が含まれています。エラーの種類はReferenceErrorで、xが未定義であること。例外がerror.jsの3行目5列目で発生したこと。メッセージの後には例外のスタックトレースが表示されています。スタックトレースとは、プログラムの実行過程を記録した内容で、どの処理によってエラーが発生したかが書かれています。スタックトレースの最初の行が実際に例外が発生した場所です。例外が発生しています次の行には、そのコードの呼び出し元が記録されています。3行目のコードを実行したのは5行目のfn関数の呼び出しですこのように、スタックトレースは上から下へ呼び出し元をたどれるように記録されています。コンソールに表示されるエラーログには多くの情報が含まれています。MDNのJavaScriptエラーリファレンスには、ブラウザが投げるビルトインエラーの種類とメッセージが網羅されています。開発中にビルトインエラーが発生したときには、リファレンスを見て解決方法を探すとよいでしょう。console.errorとスタックトレースconsole.errorメソッドではメッセージと合わせてスタックトレースをコンソールへ出力できます。次のコードを実行して、console.logとconsole.errorの出力結果を見比べてみます。console.error("エラーメッセージ");}fn();このコードをFirefoxで実行するとコンソール出力は次の図のようになります。console.logはメッセージだけなのに対して、console.errorではメッセージと共にスタックトレースが出力されます。そのため、エラーが発生した場合のコンソールへのメッセージ出力にconsole.errorを利用することでデバッグがしやすくなります。ほとんどのブラウザにはconsole.logやconsole.errorの出力をフィルターリングできる機能が備わっています。ただのログ出力にはconsole.logを使い、エラーに関するログ出力にはconsole.errorと使うことで、ログの重要度が区別しやすくなります。まとめこの章では、例外処理とエラーオブジェクトについて学びました。try...catch構文はtryブロック内で発生した例外を処理できるcatch節とfinally節は、両方またはどちらか片方を記述するthrow文は例外を投げることができ、Errorオブジェクトを例外として投げるErrorオブジェクトには、ECMAScript仕様や実行環境で定義されたビルトインエラーがあるErrorオブジェクトには、スタックトレースが記録され、デバッグに役立てられる。