aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/web/javascript/reference/statements/label/index.html
blob: e05f42627541b5639353ec31e8caa444b7a6336a (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
196
197
198
199
200
201
202
203
---
title: label
slug: Web/JavaScript/Reference/Statements/label
tags:
  - JavaScript
  - Statement
  - 语句
translation_of: Web/JavaScript/Reference/Statements/label
---
<div>{{jsSidebar("Statements")}}</div>

<p><strong>标记语句</strong>可以和 {{jsxref("Statements/break", "break")}}{{jsxref("Statements/continue", "continue")}} 语句一起使用。标记就是在一条语句前面加个可以引用的标识符(identifier)。</p>

<div>  {{EmbedInteractiveExample("pages/js/statement-label.html")}}</div>



<div class="note">
<p><strong>备注:</strong>使用标记的循环或语句块非常罕见。通常情况下,可以使用函数调用而不是(基于标记的)循环跳转。</p>
</div>

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

<pre class="syntaxbox"><em>label</em> :
   <em>statement</em>
</pre>

<dl>
 <dt><code>label</code></dt>
 <dd>任何不属于保留关键字的 JavaScript 标识符。</dd>
 <dt><code>statement</code></dt>
 <dd>JavaScript 语句。<code>break</code> 可用于任何标记语句,而 <code>continue</code> 可用于循环标记语句。</dd>
</dl>

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

<p>可使用一个标签来唯一标记一个循环,然后使用 <code>break</code> 或 <code>continue</code> 语句来指示程序是否中断循环或继续执行。</p>

<p>需要注意的是,JavaScript 没有 <code>goto</code> 语句,标记只能和 <code>break</code> 或 <code>continue</code> 一起使用。</p>

<p><a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a>中,你不能使用 “<code>let</code>” 作为标签名称。它会抛出一个 {{jsxref("SyntaxError")}}(因为 let 是一个保留的标识符)。</p>

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

<h3 id="在_for_循环中使用带标记的_continue_语句"><code>for</code> 循环中使用带标记的 <code>continue</code> 语句</h3>

<pre class="brush: js">    var i, j;

    loop1:
    for (i = 0; i &lt; 3; i++) {      //The first for statement is labeled "loop1"
       loop2:
       for (j = 0; j &lt; 3; j++) {   //The second for statement is labeled "loop2"
          if (i === 1 &amp;&amp; j === 1) {
             continue loop1;
          }
          console.log('i = ' + i + ', j = ' + j);
       }
    }

// Output is:
//   "i = 0, j = 0"
//   "i = 0, j = 1"
//   "i = 0, j = 2"
//   "i = 1, j = 0"
//   "i = 2, j = 0"
//   "i = 2, j = 1"
//   "i = 2, j = 2"
// Notice how it skips both "i = 1, j = 1" and "i = 1, j = 2"
</pre>

<h3 id="使用带标记的_continue_语句">使用带标记的 <code>continue</code> 语句</h3>

<p>若给定一个数据数组和一个测试数组,则下面的例子会统计通过测试的数据的数量。</p>

<pre class="brush: js">var itemsPassed = 0;
var i, j;

top:
for (i = 0; i &lt; items.length; i++) {
  for (j = 0; j &lt; tests.length; j++) {
    if (!tests[j].pass(items[i])) {
      continue top;
    }
  }

  itemsPassed++;
}</pre>

<h3 id="在_for_循环中使用带标记的_break"><code>for</code> 循环中使用带标记的 <code>break</code></h3>

<pre class="brush: js">var i, j;

loop1:
for (i = 0; i &lt; 3; i++) {      //The first for statement is labeled "loop1"
   loop2:
   for (j = 0; j &lt; 3; j++) {   //The second for statement is labeled "loop2"
      if (i == 1 &amp;&amp; j == 1) {
         break loop1;
      }
      console.log("i = " + i + ", j = " + j);
   }
}

// Output is:
//   "i = 0, j = 0"
//   "i = 0, j = 1"
//   "i = 0, j = 2"
//   "i = 1, j = 0"
// Notice the difference with the previous continue example</pre>

<h3 id="Example_3">使用带标记的 <code>break</code> 语句</h3>

<p>若给定一个数据数组和一个测试数组,则下面的例子会判断是否所有数据均通过了测试。</p>

<pre class="brush: js">var allPass = true;
var i, j;

top:
for (i = 0; items.length; i++)
  for (j = 0; j &lt; tests.length; i++)
    if (!tests[j].pass(items[i])){
      allPass = false;
      break top;
    }</pre>

<h3 id="在标记块中使用_break">在标记块中使用 <code>break</code></h3>

<p>你可以在代码块中使用标记,但只有 <code>break</code> 语句可以使用非循环标记。</p>

<pre class="brush: js">foo: {
  console.log('face');
  break foo;
  console.log('this will not be executed');
}
console.log('swap');

// this will log:

// "face"
// "swap</pre>

<h3 id="标记函数声明">标记函数声明</h3>

<p>从ECMAScript 2015开始,标准的函数声明现在对规范的 <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-labelled-function-declarations">Web 兼容性附件</a>中的非严格代码进行了标准化。</p>

<pre class="brush: js">L: function F() {}</pre>

<p><a href="/zh-CN/docs/Web/JavaScript/Reference/Strict_mode">严格模式</a>中,这会抛出 {{jsxref("SyntaxError")}}</p>

<pre class="brush: js">'use strict';
L: function F() {}
// SyntaxError: functions cannot be labelled
</pre>

<p>无论是否处于严格模式下,<a href="/zh-CN/docs/Web/JavaScript/Reference/Statements/function*">生成器函数</a>都不能被标记:</p>

<pre class="brush: js">L: function* F() {}
// SyntaxError: generator functions cannot be labelled</pre>

<h2 id="规范">规范</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">规范</th>
   <th scope="col">状态</th>
   <th scope="col">备注</th>
  </tr>
  <tr>
   <td>{{SpecName('ES3')}}</td>
   <td>{{Spec2('ES3')}}</td>
   <td>Initial definition. Implemented in JavaScript 1.2</td>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-12.12', 'Labelled statement')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ES6', '#sec-labelled-statements', 'Labelled statement')}}</td>
   <td>{{Spec2('ES6')}}</td>
   <td></td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-labelled-statements', 'Labelled statement')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="浏览器兼容性">浏览器兼容性</h2>



<p>{{Compat("javascript.statements.label")}}</p>

<h2 id="参见">参见</h2>

<ul>
 <li>{{jsxref("Statements/break", "break")}}</li>
 <li>{{jsxref("Statements/continue", "continue")}}</li>
</ul>