Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。

try...catch

BaselineWidely available

try...catch 语句由一个try 块和一个catch 块或finally 块(或两者皆有)组成。首先执行try 块中的代码,如果它抛出异常,则将执行catch 块中的代码。finally 块中的代码将在控制流退出整个结构之前始终被执行。

尝试一下

try {  nonExistentFunction();} catch (error) {  console.error(error);  // Expected output: ReferenceError: nonExistentFunction is not defined  // (Note: the exact output may be browser-dependent)}

语法

js
try {  tryStatements} catch (exceptionVar) {  catchStatements} finally {  finallyStatements}
tryStatements

要执行的语句。

catchStatements

try 块抛出异常后执行的语句。

exceptionVar可选

可选的标识符或模式,用于保存关联的catch 块所捕获到的异常。如果catch 块不使用异常的值,你可以省略exceptionVar 及其周围的括号。

finallyStatements

在控制流退出try...catch...finally 结构之前执行的语句。这些语句无论是否抛出或捕获异常都会执行。

描述

try 语句总是以try 块开始。并且,至少存在catch 块或finally 块。也可以同时存在catchfinally 块。这为我们提供了try 语句的三种形式:

  • try...catch
  • try...finally
  • try...catch...finally

与其他结构(如iffor)不同,trycatchfinally 块必须是,而不是单个语句。

js
try doSomething(); // SyntaxErrorcatch (e) console.log(e);

catch 块包含指定在try 块中抛出异常时要执行的语句。如果try 块(或在try 块内部调用的函数)中的任何语句抛出异常,则立即转移到catch 块。如果try 块中没有抛出异常,则跳过catch 块。

finally 块总是在控制流退出try...catch...finally 结构之前执行。它总是执行,无论是否抛出或捕获异常。

你可以嵌套多个try 语句。如果内部try 语句没有catch 块,则使用包裹它的try 语句的catch 块。

你可以使用try 语句来处理 JavaScript 异常。有关 JavaScript 异常的更多信息,请参阅JavaScript 指南

catch 绑定

try 块中抛出异常时,exceptionVar(即catch (e))保存了异常的值。你可以使用这个绑定获取有关抛出的异常的信息。这个绑定只能在catch 块的作用域中使用。

它不需要是单个标识符。你可以使用解构模式来一次性为多个标识符赋值。

js
try {  throw new TypeError("哦豁");} catch ({ name, message }) {  console.log(name); // “TypeError”  console.log(message); // “哦豁”}

catch 子句创建的绑定与catch 块处于同一作用域内,因此catch 块中声明的变量不能与catch 子句创建的绑定具有相同的名称。(有一个例外,但它是已弃用的语法。)

js
try {  throw new TypeError("哦豁");} catch ({ name, message }) {  var name; // SyntaxError: Identifier 'name' has already been declared  let message; // SyntaxError: Identifier 'message' has already been declared}

异常绑定是可写的。例如,你可能需要规范异常值,以确保它是一个Error 对象。

js
try {  throw "哦豁;这不是一个 Error 对象";} catch (e) {  if (!(e instanceof Error)) {    e = new Error(e);  }  console.error(e.message);}

如果你不需要异常值,你可以省略异常变量及其周围的括号。

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

finally 块

finally 块包含要在trycatch 块之后,但在try...catch...finally 块之后的语句之前执行的语句。控制流将始终进入finally 块,其执行可以按以下方式进行:

  • try 块正常执行完成(且没有抛出异常)后立即执行;
  • catch 块正常执行完成后立即执行;
  • try 块或catch 块中将要执行控制流语句(returnthrowbreakcontinue)退出块之前立即执行。

如果try 块中抛出异常,即使没有catch 块来处理异常,finally 块仍然执行,在这种情况下,异常仍然会在finally 块执行完成后立即抛出。

以下示例展示了finally 块的一个用例。这段代码打开一个文件,然后执行使用该文件的语句;finally 块确保文件在使用后总是关闭,即使抛出了异常。

js
openMyFile();try {  // 绑定资源  writeMyFile(theData);} finally {  closeMyFile(); // 始终关闭资源}

控制流语句(returnthrowbreakcontinue)在finally 块中将“覆盖”try 块或catch 块的任何正常完成值。在此示例中,try 块尝试返回 1,但在返回之前,控制流已转移到finally 块,因此finally 块的返回值将被返回。

js
function doIt() {  try {    return 1;  } finally {    return 2;  }}doIt(); // 返回 2

finally 块中使用控制流语句通常不是一个好主意。请只将其用于清理代码。

示例

无条件捕获块

当使用catch 块时,catch 块将在try 块中抛出异常时被执行。例如,在下面的代码中,控制流将被转移到catch 块。

js
try {  throw "我的异常"; // 产生异常} catch (e) {  // 处理任何异常的语句  logMyErrors(e); // 将异常对象传递给错误处理器}

catch 块指定了一个标识符(如上例中的e),它保存了异常的值。这个值只能在catch 块的作用域内使用。

条件捕获块

你可以通过将try...catch 块与if...else if...else 结构组合起来,创建“条件catch 块”。例如:

js
try {  myroutine(); // 可能会抛出三种类型的异常} catch (e) {  if (e instanceof TypeError) {    // 处理 TypeError 异常的语句  } else if (e instanceof RangeError) {    // 处理 RangeError 异常的语句  } else if (e instanceof EvalError) {    // 处理 EvalError 异常的语句  } else {    // 处理未指定异常的语句    logMyErrors(e); // 将异常对象传递给错误处理器  }}

一个常见的用例是仅捕获(并消除)一小部分预期错误,然后在其他情况下重新抛出错误:

js
try {  myRoutine();} catch (e) {  if (e instanceof RangeError) {    // 处理这个非常常见的预期错误的语句  } else {    throw e; // 重新抛出错误,没有任何改变  }}

这类似与其他语言中的语法,比如 Java:

java
try {  myRoutine();} catch (RangeError e) {  // 处理这个非常常见的预期错误的语句}// 其他错误被隐式重新抛出

嵌套 try 块

首先,让我们看看下面的代码会发生什么:

js
try {  try {    throw new Error("哦豁");  } finally {    console.log("finally");  }} catch (ex) {  console.error("外层", ex.message);}// 输出:// “finally”// “外层” “哦豁”

现在,如果我们已经在内部的try 块中通过添加catch 块捕获了异常:

js
try {  try {    throw new Error("哦豁");  } catch (ex) {    console.error("内层", ex.message);  } finally {    console.log("最终");  }} catch (ex) {  console.error("外层", ex.message);}// 输出:// “内层” “哦豁”// “最终”

现在,让我们重新抛出错误。

js
try {  try {    throw new Error("哦豁");  } catch (ex) {    console.error("内层", ex.message);    throw ex;  } finally {    console.log("最终");  }} catch (ex) {  console.error("外层", ex.message);}// 输出:// “内层” “哦豁”// “最终”// “外层” “哦豁”

任何特定的异常只会被直接包裹它的catch 块捕获一次,除非该异常被重新抛出。当然,如果在“内部”代码块中触发了任何新的异常(因为catch 块中的代码可能会执行某些操作并抛出异常),这些异常将由外部的catch 块捕获。

从 finally 块返回

如果finally 块返回一个值,这个值将成为整个try-catch-finally 语句的返回值,而不管trycatch 块中的return 语句。这包括catch 块中抛出的异常。

js
(() => {  try {    try {      throw new Error("哦豁");    } catch (ex) {      console.error("内层", ex.message);      throw ex;    } finally {      console.log("最终");      return;    }  } catch (ex) {    console.error("外层", ex.message);  }})();// 输出:// “内层” “哦豁”// “最终”

外层的“哦豁”不会被抛出,因为finally 块中的return 语句将控制流转移到外部。同样的规则也适用于catch 块中返回的值。

规范

Specification
ECMAScript® 2026 Language Specification
# sec-try-statement

浏览器兼容性

参见

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp