aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/statements/throw/index.html
blob: aee6a02e790afb87d796b4eadfeae4f7f6f14769 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
---
title: throw
slug: Web/JavaScript/Reference/Statements/throw
tags:
  - JavaScript
  - Statement
translation_of: Web/JavaScript/Reference/Statements/throw
---
<div>{{jsSidebar("Statements")}}</div>

<p><strong><code>throw</code>语句</strong>用来抛出一个用户自定义的异常。当前函数的执行将被停止(<code>throw</code>之后的语句将不会执行),并且控制将被传递到调用堆栈中的第一个<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/try...catch"><code>catch</code></a>块。如果调用者函数中没有<code>catch</code>块,程序将会终止。</p>

<p>{{EmbedInteractiveExample("pages/js/statement-throw.html")}}</p>

<div class="hidden">
<p>The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p>
</div>

<h2 id="语法">语法</h2>

<pre class="syntaxbox">throw <em>expression</em>; </pre>

<dl>
 <dt><code>expression</code></dt>
 <dd>要抛出的表达式。</dd>
</dl>

<h2 id="描述">描述</h2>

<p>使用<code>throw</code>语句来抛出一个异常。当你抛出异常时,<code>expression</code> 指定了异常的内容。下面的每行都抛出了一个异常:</p>

<pre class="brush: js">throw "Error2"; // 抛出了一个值为字符串的异常
throw 42;       // 抛出了一个值为整数42的异常
throw true;     // 抛出了一个值为true的异常</pre>

<p>注意<code>throw</code>语句同样受到<a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion">自动分号插入(ASI</a>)机制的控制,在<code>throw</code>关键字和值之间不允许有行终止符。</p>

<h2 id="示例">示例</h2>

<h3 id="抛出一个对象">抛出一个对象</h3>

<p>你可以在抛出异常时指定一个对象。然后可以在<code>catch</code>块中引用对象的属性。以下示例创建一个类型为<code>UserException</code>的对象,并在<code>throw</code>语句中使用它。</p>

<pre class="brush: js">function UserException(message) {
   this.message = message;
   this.name = "UserException";
}
function getMonthName(mo) {
   mo = mo-1; // 调整月份数字到数组索引 (1=Jan, 12=Dec)
   var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
      "Aug", "Sep", "Oct", "Nov", "Dec"];
   if (months[mo] !== undefined) {
      return months[mo];
   } else {
      throw new UserException("InvalidMonthNo");
   }
}

try {
   // statements to try
   var myMonth = 15; // 15 超出边界并引发异常
   var monthName = getMonthName(myMonth);
} catch (e) {
   var monthName = "unknown";
   console.log(e.message, e.name); // 传递异常对象到错误处理
}
</pre>

<h3 id="另一个抛出异常对象的示例">另一个抛出异常对象的示例</h3>

<p>下面的示例中测试一个字符串是否是美国邮政编码。如果邮政编码是无效的,那么<code>throw</code>语句将会抛出一个类型为 <code>ZipCodeFormatException</code>的异常对象实例。</p>

<pre class="brush: js">/*
 * 创建 ZipCode 示例.
 *
 * 可被接受的邮政编码格式:
 *    12345
 *    12345-6789
 *    123456789
 *    12345 6789
 *
 * 如果构造函数参数传入的格式不符合以上任何一个格式,将会抛出异常。
 */

function ZipCode(zip) {
   zip = new String(zip);
   pattern = /[0-9]{5}([- ]?[0-9]{4})?/;
   if (pattern.test(zip)) {
      // zip code value will be the first match in the string
      this.value = zip.match(pattern)[0];
      this.valueOf = function() {
         return this.value
      };
      this.toString = function() {
         return String(this.value)
      };
   } else {
      throw new ZipCodeFormatException(zip);
   }
}

function ZipCodeFormatException(value) {
   this.value = value;
   this.message = "不是正确的邮政编码";
   this.toString = function() {
      return this.value + this.message
   };
}

/*
 * 这可能是一个验证美国地区中的脚本
 */

const ZIPCODE_INVALID = -1;
const ZIPCODE_UNKNOWN_ERROR = -2;

function verifyZipCode(z) {
   try {
      z = new ZipCode(z);
   } catch (e) {
      if (e instanceof ZipCodeFormatException) {
         return ZIPCODE_INVALID;
      } else {
         return ZIPCODE_UNKNOWN_ERROR;
      }
   }
   return z;
}

a = verifyZipCode(95060);         // 返回 95060
b = verifyZipCode(9560);          // 返回 -1
c = verifyZipCode("a");           // 返回 -1
d = verifyZipCode("95060");       // 返回 95060
e = verifyZipCode("95060 1234");  // 返回 95060 1234
</pre>

<h3 id="重新抛出异常">重新抛出异常</h3>

<p>你可以使用<code>throw</code>来抛出异常。下面的例子捕捉了一个异常值为数字的异常,并在其值大于50后重新抛出异常。重新抛出的异常传播到闭包函数或顶层,以便用户看到它。</p>

<pre class="brush: js">try {
   throw n; // 抛出一个数值异常
} catch (e) {
   if (e &lt;= 50) {
      // 异常在 1-50 之间时,直接处理
   } else {
      // 异常无法处理,重新抛出
      throw e;
   }
}
</pre>

<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.13', 'throw statement')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-throw-statement', 'throw statement')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td> </td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-throw-statement', 'throw statement')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </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.throw")}}</p>

<h2 id="相关链接">相关链接</h2>

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/try...catch"><code>try...catch</code></a></li>
</ul>