この翻訳は不完全です。英語から この記事を翻訳 してください。

try…catch 構文は試したい文のブロックをマークし、例外を投げる必要がある場合のレスポンスを指定するための構文です。

構文

try {
   try_statements
}
[catch (exception_var_1 if condition_1) { // non-standard
   catch_statements_1
}]
...
[catch (exception_var_2) {
   catch_statements_2
}]
[finally {
   finally_statements
}]
try_statements
実行される文です。
catch_statements_1, catch_statements_2
try ブロックの中で例外が投げられた場合に実行される文です。
exception_var_1, exception_var_2
関連する catch 節に対して例外オブジェクトを保持する識別子です。
condition_1
条件式です。
finally_statements
try 文が完了した後に実行される文です。これらの文は、例外が投げられたり捕捉されたかどうかに関係なく実行されます。

説明

try 文は、1 つ以上の文を含む try ブロック、および少なくとも 1 つの catch 節、または finally 節、もしくはその両方から成り立っています。すなわち、try 文には 3 つの形式があります:

  1. try...catch
  2. try...finally
  3. try...catch...finally

catch 節は、例外が try ブロックの中で投げられたのなら何をすべきか指定する文を含みます。すなわち、try ブロックは成功すべきで、それが成功しなかったのなら、制御は catch ブロックに渡るべきです。try ブロック内 (または try ブロック内から呼び出された関数の中) の任意の文が例外を投げたのなら、制御は即座に catch 節へ移ります。例外が try ブロックの中で投げられなかったのなら、catch 節は飛ばされます。

finally 節は、try ブロックおよび( 1 つまたは複数の)catch 節が実行された後、なおかつ try 文の次の文の前に実行されます。これは、例外が投げられた、または捕捉されたかどうかに関係なく、常に実行されます。

1 つ以上の try 文をネストすることもできます。内側の try 文が catch 節を持たないのなら、囲んでいる try 文の catch 節に入ります。

JavaScript の例外を操作するためにも try 文を使います。JavaScript の例外に関する情報は JavaScript ガイドを参照してください。

無条件 catch

単独の無条件 catch 節が使われたときは、任意の例外が投げられると catch 節に入ります。たとえば、次のコードの中で例外が生じたとき、制御は catch 節に移動します。

try {
   throw "myException"; // 例外を生成します
}
catch (e) {
   // 任意の例外を操作するための文
   logMyErrors(e); // エラーハンドラに例外オブジェクトを渡します
}

catch ブロックは throw 文で指定した値を保持する識別子(上記の例では e )を指定します。The catch block is unique in that JavaScript creates this identifier when the catch block is entered, and it adds it to the current scope; the identifier lasts only for the duration of the catch block; after the catch block finishes executing, the identifier is no longer available.

条件付き catch

非標準
この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

特定の例外を操作するために、1 つ以上の条件付き catch 節を使うこともできます。この場合、特定の例外が投げられると、適切な catch 節に入ります。次の例では、try ブロックの中のコードは 3 つの例外: TypeErrorRangeError、および EvalError、を投げる可能性があります。例外が生じたとき、制御は適切な catch 節に移動します。例外が、指定された例外のどれでもなく、かつ無条件 catch 節が見つかったのなら、制御はその catch 節に移動します。

1 つ以上の条件付き catch 節とともに無条件 catch 節を使うのなら、無条件 catch 節は最後に指定されなくてはいけません。そうでなければ、無条件 catch 節が全種類の例外を、それらが条件付きのものに到達する前に、途中で捕捉します。

注: この機能は ECMAScript 仕様の一部ではなく、Firefox 59 で削除されています。現在のブラウザではサポートされていません。

try {
   myroutine(); // 3 つの例外を投げる可能性があります
} catch (e if e instanceof TypeError) {
   // TypeError 例外を操作するための文
} catch (e if e instanceof RangeError) {
   // RangeError 例外を操作するための文
} catch (e if e instanceof EvalError) {
   // EvalError 例外を操作するための文
} catch (e) {
   // 任意の指定されていない例外を操作するための文
   logMyErrors(e); // エラーハンドラに例外オブジェクトを渡します
}

続いて「条件付き catch 節」と同じことを ECMAScript 仕様に準拠した JavaScript を使って実装する方法も示します(これは明らかに冗長ですが、かわりにどの環境でも動作します):

try {
    myroutine(); // may throw three types of exceptions
} catch (e) {
    if (e instanceof TypeError) {
        // statements to handle TypeError exceptions
    } else if (e instanceof RangeError) {
        // statements to handle RangeError exceptions
    } else if (e instanceof EvalError) {
        // statements to handle EvalError exceptions
    } else {
       // statements to handle any unspecified exceptions
       logMyErrors(e); // pass exception object to error handler
    }
}

例外識別子

例外が try ブロックの中で投げられたときは、exception_var (たとえば、catch (e) における e) が throw 文により指定された値を保持します。投げられた例外についての情報を得るために、この識別子を使うことができます。この識別子は catch 節にローカルです。すなわち、これは catch 節に入ったときに作成され、catch 節が実行を終了した後では、この識別子はもはや利用できません。

Firefox 58(および TypeScript 2.5 以降)では、例外が使用されていない場合は、次のコードのように識別子を省略できます。ですが、これを書いている時点(2018年8月)では、これをサポートする提案はまだ ECMAScript 標準に含まれていないので、この構文は他のブラウザでは動作しないかもしれません。

function isValidJSON(text) {
    try {
        JSON.parse(text);
        return true;
    } catch {
        return false;
    }
}

finally

finally 節は、try ブロックおよび (1 つまたは複数の) catch 節が実行された後、なおかつ try 文の次の文の前に実行される文を含みます。but before the statements following the try..catch..finally block. finally 節は、例外が投げられたかどうかに関係なく実行されます。例外が投げられたのなら、たとえ例外を操作する catch 節がなかったとしても、finally 節の中の文は実行されます。

例外が生じたときに、スクリプトを潔く失敗させるために finally 節を使うことができます。たとえば、スクリプトが結び付けていたリソースを解放する必要があるかもしれません。

It may seem strange to have a special exception-related clause that executes regardless of whether there is an exception, but this construct actually does serve a purpose.  The important point is not that the finally-clause always executes, but rather that ordinary code following a try..catch does not. 

For instance, if another exception occurs inside a try's catch-block, any remaining code in the same outer try-block enclosing that try..catch (or in the main flow, if not in an outer try-block) , will not get executed, since control is immediately transferred to the outer try's catch-block (or the internal error-generator, if not in a try-block).  

Thus, any routine cleanup code done in that enclosed (or the main) section before it exits, will be skipped.  However, If the try-block has a finally-block, then that finally-block code will be executed first to permit any such cleanup, and THEN the other try's catch-block (or the error-generator) will get control to handle the second exception.  

Now, if that routine cleanup must be done whether or not the try..catch code succeeds, then if the finally-block only executed after an exception, the same cleanup code would have to be duplicated both inside and outside the finally-block, and therefore there is no reason not to have just the finally-block alone, and let it execute regardless of exceptions or not.

次の例ではファイルを開き、そのファイルを使う文を実行します (サーバーサイド JavaScript ではファイルにアクセスできます)。ファイルが開かれている間に例外が投げられたのなら、スクリプトが失敗する前に finally 節はファイルを閉じます。The code in finally also executes upon explicitly returning from try or catch block.

openMyFile()
try {
   // リソースを結び付けます
   writeMyFile(theData);
}
finally {
   closeMyFile(); // リソースを常に閉じます
}

入れ子になった try ブロック

最初に、これで何が起きるか見てみましょう:

try {
  try {
    throw new Error('oops');
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "finally"
// "outer" "oops"

続いて、catch ブロックを追加して内部の try ブロックで例外をキャッチしてみます。

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"

そして、エラーを再スローします。

try {
  try {
    throw new Error('oops');
  }
  catch (ex) {
    console.error('inner', ex.message);
    throw ex;
  }
  finally {
    console.log('finally');
  }
}
catch (ex) {
  console.error('outer', ex.message);
}

// Output:
// "inner" "oops"
// "finally"
// "outer" "oops"

再スローされない限り任意の例外は、最も内側のキャッチブロックで一度だけ捕捉されます。もちろん、何らかの例外が "内部" のブロックで発生した場合(catch ブロックのコードで何らかのスローが発生した場合)、"外部" のブロックでキャッチされます。

finally ブロックからの return

finally ブロックが値を返した場合、try ブロックと catch ブロックの return ステートメントにかからわず、この値が try-catch-finally 全体の戻り値になります。これは catch ブロック内でスローされた例外も含みます:

(function() {
  try {
    try {
      throw new Error('oops');
    }
    catch (ex) {
      console.error('inner', ex.message);
      throw ex;
    }
    finally {
      console.log('finally');
      return;
    }
  }
  catch (ex) {
    console.error('outer', ex.message);
  }
})();

// Output:
// "inner" "oops"
// "finally"

外部("outer")の "oops" は finally ブロックで return されているため、スローされません。同じことが、catch ブロックから返されているそのほかの値にも適用されます。

仕様

仕様 ステータス コメント
ECMAScript 3rd Edition (ECMA-262) 標準 初期定義。JavaScript 1.4 で実装されました。
ECMAScript 5.1 (ECMA-262)
try statement の定義
標準  
ECMAScript 2015 (6th Edition, ECMA-262)
try statement の定義
標準  
ECMAScript Latest Draft (ECMA-262)
try statement の定義
ドラフト 現在の ECMA-262 標準には含まれていません。複数の catch 節と条件付き catch 節(SpiderMonkey 拡張、JavaScript 1.5)。

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
try...catchChrome 完全対応 ありEdge 完全対応 ありFirefox 完全対応 1IE 完全対応 6Opera 完全対応 ありSafari 完全対応 ありWebView Android 完全対応 ありChrome Android 完全対応 ありFirefox Android 完全対応 4Opera Android 完全対応 ありSafari iOS 完全対応 ありSamsung Internet Android 完全対応 ありnodejs 完全対応 あり
Conditional clauses
非推奨非標準
Chrome 未対応 なしEdge 未対応 なしFirefox 未対応 1 — 59IE 未対応 なしOpera 未対応 なしSafari 未対応 なしWebView Android 未対応 なしChrome Android 未対応 なしFirefox Android 未対応 4 — 59Opera Android 未対応 なしSafari iOS 未対応 なしSamsung Internet Android 未対応 なしnodejs 未対応 なし
Optional catch bindingChrome 完全対応 66Edge 未対応 なしFirefox 完全対応 58IE 未対応 なしOpera 完全対応 53Safari 完全対応 11.1WebView Android 完全対応 66Chrome Android 完全対応 66Firefox Android 完全対応 58Opera Android 完全対応 47Safari iOS 完全対応 11.3Samsung Internet Android 未対応 なしnodejs 完全対応 10.0.0

凡例

完全対応  
完全対応
未対応  
未対応
非標準。ブラウザー間の互換性が低い可能性があります。
非標準。ブラウザー間の互換性が低い可能性があります。
非推奨。新しいウェブサイトでは使用しないでください。
非推奨。新しいウェブサイトでは使用しないでください。

関連項目

ドキュメントのタグと貢献者

最終更新者: tscontenna,