JavaScript/例外処理

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動
オブジェクト JavaScript
例外処理
正規表現

例外処理(れいがいしょり、exception handling)とは、プログラムに異常が発生した場合に現在の処理を中断し、エラーメッセージを表示するなどの処理を行うことをいいます。

throw[編集]

throw文は例外を発生させます。

function reduce(array, callback, initialValue) {
    if (typeof callback != 'function') {
        throw new Error(callback + " is not a function");
    }
    // ...
}

reduce([], null); // "null is not a function" とエラー

throw文にはどんな値でも渡すことができますが、一般的にはErrorなどの例外オブジェクトを渡します。例外オブジェクトは生成されるときに例外発生時の状況を記録するため、デバッグが容易になるからです。特にReferenceErrorオブジェクトやSyntaxErrorオブジェクト、TypeErrorオブジェクトなどの例外オブジェクトは、エラーの種類(参照エラーや構文エラー、型エラーなど)を明示するのに用いられます。

function reduce( array, callback, initialValue ) {
    if ( typeof callback != 'function' ) {
        throw new TypeError( callback + " is not a function" );
    }
    // ...
}

reduce( [], null ); // "TypeError: null is not a function" とエラー

throw文で例外が投げられると、以降のプログラムの実行は中断され、処理系のエラーコンソールにエラーが表示されます。

try-catch[編集]

try文のブロックの中で例外が発生すると、catch節のブロックが実行され、例外が捕捉されます。try文のブロックで例外が発生しなかった場合は、catch節のブロックは実行されません。catch節のブロックが実行された後も、catch節のブロックの中で例外が発生しなければ、プログラムは中断せずに以降の処理を継続します。

try {
    throw new Error( "エラー!" );
}
catch (e) {
    alert(e.message); // "エラー!" と警告
}

alert("しかし処理は続行…");

catch節は複数置くことができます。また、catch節は必ずthrow文のパラメータeを受け取らなければなりません。eの変数名は任意の識別子。

finally[編集]

finally節は事後処理を行います。catch節の後にfinally節を書くと、例外が発生してもしなくてもfinally節が実行されます。

try {
    alert("try");     // 0. "try" と警告
}
catch (e) {
    alert("catch");
}
finally {
    alert("finally"); // 1. "finally" と警告
}

alert("outside");     // 2. "outside" と警告

例外が発生した場合は、catch節が実行された後にfinally節が実行されます。finally節が実行された後は以降の処理を継続します。

try {
    alert("try");     // 0. "try" と警告
    throw new Error();
}
catch (e) {
    alert("catch");   // 1. "catch" と警告
}
finally {
    alert("finally"); // 2. "finally" と警告
}

alert("outside");     // 3. "outside" と警告

try文の後にはcatch節またはfinally節のいずれか、もしくは両方を置かなければなりません。catch節を除いたtry-finally節では、例外が発生してもしなくてもfinally節は実行されますが、catch節によって例外が捕捉されないので、例外が発生した場合は以降の処理を中断します。

大域脱出[編集]

例外は大域脱出に使うこともできます。大域脱出とは、入れ子になった制御構造の内側から外側に制御を戻すことです。breakreturnは最内側の制御構造(for/while/switchと関数)を抜け出すだけですが、例外をthrowすると文や関数を超えて制御が移ります。この性質を利用すると二重以上のループや関数を脱出することができるのです。

ですが、大域脱出を使うことは極力避けてください。breakやreturnをラベルと共に使用することで、ほとんどの場合は帯域脱出を使うことなく要件を達成できます。 例えば、Array.prototype.forEachメソッドの様にcallbackで反復処理を行う場合は、例外による帯域脱出が適用なケースです。

このページ「JavaScript/例外処理」は、まだ書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にトークページへどうぞ。