diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/zh-cn/web/javascript/reference/statements/try...catch | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/zh-cn/web/javascript/reference/statements/try...catch')
-rw-r--r-- | files/zh-cn/web/javascript/reference/statements/try...catch/index.html | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/files/zh-cn/web/javascript/reference/statements/try...catch/index.html b/files/zh-cn/web/javascript/reference/statements/try...catch/index.html new file mode 100644 index 0000000000..ff290ab4ba --- /dev/null +++ b/files/zh-cn/web/javascript/reference/statements/try...catch/index.html @@ -0,0 +1,302 @@ +--- +title: try...catch +slug: Web/JavaScript/Reference/Statements/try...catch +tags: + - Error + - Exception + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Statements/try...catch +--- +<div>{{jsSidebar("Statements")}}</div> + +<p><strong><code>try...catch</code></strong>语句标记要尝试的语句块,并指定一个出现异常时抛出的响应。</p> + +<p>{{EmbedInteractiveExample("pages/js/statement-trycatch.html")}}</p> + +<h2 id="语法">语法</h2> + +<pre class="syntaxbox">try { + <em>try_statements</em> +} +[catch (<em>exception_var_1</em> if <em>condition_1</em>) { // non-standard + <em>catch_statements_1</em> +}] +... +[catch (<em>exception_var_2</em>) { + <em>catch_statements_2</em> +}] +[finally { + <em>finally_statements</em> +}] +</pre> + +<dl> + <dt><code>try_statements</code></dt> + <dd>需要被执行的语句。</dd> +</dl> + +<dl> + <dt><code>catch_statements_1</code>, <code>catch_statements_2</code></dt> + <dd>如果在<code>try</code>块里有异常被抛出时执行的语句。</dd> +</dl> + +<dl> + <dt><code>exception_var_1</code>, <code>exception_var_2</code></dt> + <dd>用于保存关联<code>catch</code>子句的异常对象的标识符。</dd> +</dl> + +<dl> + <dt><code>condition_1</code></dt> + <dd>一个条件表达式。</dd> +</dl> + +<dl> + <dt><code>finally_statements</code></dt> + <dd>在<code>try</code>语句块之后执行的语句块。无论是否有异常抛出或捕获这些语句都将执行。</dd> +</dl> + +<h2 id="描述">描述</h2> + +<p><code>try</code>语句包含了由一个或者多个语句组成的<code>try</code>块, 和至少一个<code>catch</code>块或者一个<code>finally</code>块的其中一个,或者两个兼有, 下面是三种形式的<code>try</code>声明:</p> + +<ol> + <li><code>try...catch</code></li> + <li><code>try...finally</code></li> + <li><code>try...catch...finally</code></li> +</ol> + +<p><code>catch</code>子句包含<code>try</code>块中抛出异常时要执行的语句。也就是,你想让<code>try</code>语句中的内容成功, 如果没成功,你想控制接下来发生的事情,这时你可以在<code>catch</code>语句中实现。 如果在<code>try</code>块中有任何一个语句(或者从<code>try</code>块中调用的函数)抛出异常,控制立即转向<code>catch</code>子句。如果在<code>try</code>块中没有异常抛出,会跳过<code>catch</code>子句。</p> + +<p><code>finally</code>子句在<code>try</code>块和<code>catch</code>块之后执行但是在下一个<code>try</code>声明之前执行。无论是否有异常抛出或捕获它总是执行。</p> + +<p>你可以嵌套一个或者更多的<code>try</code>语句。如果内部的<code>try</code>语句没有<code>catch</code>子句,那么将会进入包裹它的<code>try</code>语句的<code>catch</code>子句。</p> + +<p>你也可以用<code>try</code>语句去处理 JavaScript 异常。参考<a href="/zh-CN/docs/Web/JavaScript/Guide">JavaScript 指南</a>了解更多关于 Javascript 异常的信息。</p> + +<h3 id="无条件的catch块">无条件的<code>catch</code>块</h3> + +<p>当使用单个无条件<code>catch</code>子句时,抛出的任何异常时都会进入到<code>catch</code>块。例如,当在下面的代码中发生异常时,控制转移到<code>catch</code>子句。</p> + +<pre class="brush: js">try { + throw "myException"; // generates an exception +} +catch (e) { + // statements to handle any exceptions + logMyErrors(e); // pass exception object to error handler +} +</pre> + +<p><code>catch</code>块指定一个标识符(在上面的示例中为e),该标识符保存由<code>throw</code>语句指定的值。<code>catch</code>块是唯一的,因为当输入<code>catch</code>块时,JavaScript 会创建此标识符,并将其添加到当前作用域;标识符仅在<code>catch</code>块执行时存在;<code>catch</code>块执行完成后,标识符不再可用。</p> + +<h3 id="条件catch块">条件<code>catch</code>块</h3> + +<p>{{non-standard_header}}</p> + +<p>你也可以用一个或者更多条件<code>catch</code>子句来处理特定的异常。在这种情况下,当异常抛出时将会进入合适的<code>catch</code>子句中。在下面的代码中,<code>try</code>块的代码可能会抛出三种异常:{{jsxref("TypeError")}},{{jsxref("RangeError")}}和{{jsxref("EvalError")}}。当一个异常抛出时,控制将会进入与其对应的<code>catch</code>语句。如果这个异常不是特定的,那么控制将转移到无条件<code>catch</code>子句。</p> + +<p>当用一个无条件<code>catch</code>子句和一个或多个条件语句时,无条件<code>catch</code>子句必须放在最后。否则当到达条件语句之前所有的异常将会被非条件语句拦截。</p> + +<p>提醒:这个功能不符合 ECMAscript 规范。</p> + +<pre class="brush: js">try { + myroutine(); // may throw three types of exceptions +} catch (e if e instanceof TypeError) { + // statements to handle TypeError exceptions +} catch (e if e instanceof RangeError) { + // statements to handle RangeError exceptions +} catch (e if e instanceof EvalError) { + // statements to handle EvalError exceptions +} catch (e) { + // statements to handle any unspecified exceptions + logMyErrors(e); // pass exception object to error handler +} +</pre> + +<p>下面用符合 ECMAscript 规范的简单的 JavaScript 来编写相同的“条件catch子句”(显然更加<span class="s1">冗长的</span>,但是可以在任何地方运行):</p> + +<pre class="brush: js">try { + myRoutine(); +} catch (e) { + if (e instanceof RangeError) { + // statements to handle this very common expected error + } else { + throw e; // re-throw the error unchanged + } +}</pre> + +<h3 id="异常标识符">异常标识符</h3> + +<p>当<code>try</code>块中的抛出一个异常时, <em><code>exception_var</code></em>(如<code>catch (e)</code>中的<code>e</code>)用来保存被抛出声明指定的值。你可以用这个标识符来获取关于被抛出异常的信息。</p> + +<p>这个标识符是<code>catch</code>子语句内部的。换言之,当进入<code>catch</code>子语句时标识符创建,<code>catch</code>子语句执行完毕后,这个标识符将不再可用。</p> + +<pre class="brush: js">function isValidJSON(text) { + try { + JSON.parse(text); + return true; + } catch { + return false; + } +}</pre> + +<h3 id="finally块"><code>finally</code>块</h3> + +<p><code>finally</code>块包含的语句在<code>try</code>块和<code>catch</code>之后,<code>try..catch..finally</code>块后的语句之前执行。请注意,无论是否抛出异常<code>finally</code>子句都会执行。此外,如果抛出异常,即使没有<code>catch</code>子句处理异常,<code>finally</code>子句中的语句也会执行。</p> + +<p>以下示例打开一个文件,然后执行使用该文件的语句(服务器端 JavaScript 允许您访问文件)。如果文件打开时抛出异常,则<code>finally</code>子句会在脚本失败之前关闭该文件。finally中的代码最终也会在<code>try</code>或<code>catch block</code>显式返回时执行。</p> + +<pre class="brush: js">openMyFile() +try { + // tie up a resource + writeMyFile(theData); +} +finally { + closeMyFile(); // always close the resource +} +</pre> + +<h2 id="示例">示例</h2> + +<h3 id="嵌套_try_块">嵌套 try 块</h3> + +<p>首先让我们看看这里发生什么:</p> + +<pre class="brush: js">try { + try { + throw new Error("oops"); + } + finally { + console.log("finally"); + } +} +catch (ex) { + console.error("outer", ex.message); +} + +// Output: +// "finally" +// "outer" "oops" +</pre> + +<p>现在,如果我们已经在 try 语句中,通过增加一个 catch 语句块捕获了异常</p> + +<pre class="brush: js">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" +</pre> + +<p>现在,让我们再次抛出错误。</p> + +<pre class="brush: js">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" +</pre> + +<p>任何给定的异常只会被离它最近的封闭 catch 块捕获一次。当然,在“inner”块抛出的任何新异常 (因为 catch 块里的代码也可以抛出异常),将会被“outer”块所捕获。</p> + +<h3 id="从_finally_语句块返回">从 finally 语句块返回</h3> + +<p>如果从<code>finally</code>块中返回一个值,那么这个值将会成为整个<code>try-catch-finally</code>的返回值,无论是否有<code>return</code>语句在<code>try</code>和<code>catch</code>中。这包括在<code>catch</code>块里抛出的异常。</p> + +<pre class="brush: js">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); +} + +// 注: 此 try catch 语句需要在 function 中运行才能作为函数的返回值, 否则直接运行会报语法错误 +// Output: +// "inner" "oops" +// "finally" +</pre> + +<p>因为 finally 块里的 return 语句,"oops" 没有抛出到外层,从 catch 块返回的值同样适用。</p> + +<h2 id="规范">规范</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES3')}}</td> + <td>{{Spec2('ES3')}}</td> + <td>Initial definition. Implemented in JavaScript 1.4</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-12.14', 'try statement')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-try-statement', 'try statement')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-try-statement', 'try statement')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Not part of the current ECMA-262 standard: Multiple catch clauses and conditional clauses (SpiderMonkey extension, JavaScript 1.5).</td> + </tr> + </tbody> +</table> + +<h2 id="浏览器兼容">浏览器兼容</h2> + +<div class="hidden">The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div> + +<p>{{Compat("javascript.statements.try_catch")}}</p> + +<h2 id="相关链接">相关链接</h2> + +<ul> + <li>{{jsxref("Error")}}</li> + <li>{{jsxref("Statements/throw", "throw")}}</li> +</ul> |