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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
|
---
title: Loops and iteration
slug: Web/JavaScript/Guide/Loops_and_iteration
tags:
- JavaScript
- Loop
- 教學
- 迴圈
translation_of: Web/JavaScript/Guide/Loops_and_iteration
---
<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</div>
<p>迴圈提供一個快速又簡潔的方法來重複地做某件事。這個章節的<a href="/zh-TW/docs/Web/JavaScript/Guide">JavaScript教學</a>會介紹在JavaScript可以使用的幾種不同的迭代陳述式。 </p>
<p>你可以將迴圈想成一個電腦版本的"往一個方向走X步,然後往另一個方向走Y步"的遊戲;作為範例,"往東走五步"可以用這個方法用迴圈表示:</p>
<pre class="brush: js">var step;
for (step = 0; step < 5; step++) {
// 執行五次:從step為0到4
console.log('Walking east one step');
}
</pre>
<p>有很多種不同種類的迴圈, 不過他們本質上都是做一樣的事:把一件動作重複地做一定的次數(而且也有可能做0次)。 各式各樣的迴圈機制提供了不同的方法來定義該迴圈的起始與結束。有些不同的情況下使用其中一種迴圈會比使用別種容易許多。</p>
<p>在javaScript中提供的迴圈陳述式分別為:</p>
<ul>
<li><a href="#for_陳述式">for 陳述式</a></li>
<li><a href="#do...while_陳述式">do...while 陳述式</a></li>
<li><a href="#while_陳述式">while 陳述式</a></li>
<li><a href="#label_陳述式">label 陳述式</a></li>
<li><a href="#break_陳述式">break 陳述式</a></li>
<li><a href="#continue_陳述式">continue 陳述式</a></li>
<li><a href="#for...in_陳述式">for...in 陳述式</a></li>
<li><a href="#for...of_陳述式">for...of 陳述式</a></li>
</ul>
<h2 id="for_陳述式"><code>for </code>陳述式</h2>
<p>一個<a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/for">for迴圈</a>不斷重複直到一個指定的條件式判斷為false。JavaScript的for迴圈跟Java還有C的for迴圈很相似。一個for陳述式看起來像下面這樣:</p>
<pre class="syntaxbox">for ([初始表達式]; [條件式]; [遞增表達式])
陳述式
</pre>
<p>當執行一個for迴圈時,會發生以下:</p>
<ol>
<li>如果有的話,初始表達式會被執行。這個表達式通常會初始化一或多個迴圈計數器,但是語法允許任何程度的複雜性。這個表達式也能用來宣告變數。</li>
<li>條件式會被評估。如果評估出的值為true,迴圈的敘事式便會執行。如果評估出的值為false,這個for迴圈便會中止。如果條件式被省略了,狀態就會被假設是true。</li>
<li>執行敘事式。要執行多個敘事式時,使用區塊敘事式(<code>{ ... }</code>) 來把那些敘事式歸為一組。</li>
<li>如果有更新表達式的遞增表達式便執行。然後return到第二步。</li>
</ol>
<h3 id="範例"><strong>範例</strong></h3>
<p>以下的函式包含一個用來數在一個滾動列表中被選過的選項(a {{HTMLElement("select")}} 允許複數選項的元素)的for陳述式 。這個for敘事式宣告了變數 i 並將其初始化為0。 他檢查 i ,如果 i 少於在<select>元素中的選項數量,進行接著的 if陳述式,並將 i 在每次通過迴圈後遞增。</p>
<pre class="brush: html"><form name="selectForm">
<p>
<label for="musicTypes">Choose some music types, then click the button below:</label>
<select id="musicTypes" name="musicTypes" multiple="multiple">
<option selected="selected">R&B</option>
<option>Jazz</option>
<option>Blues</option>
<option>New Age</option>
<option>Classical</option>
<option>Opera</option>
</select>
</p>
<p><input id="btn" type="button" value="How many are selected?" /></p>
</form>
<script>
function howMany(selectObject) {
var numberSelected = 0;
for (var i = 0; i < selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
alert('Number of options selected: ' + howMany(document.selectForm.musicTypes))
});
</script>
</pre>
<h2 id="do...while_陳述式"><code>do...while</code> 陳述式</h2>
<p><code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> </code><code>陳述式會不斷重複直到一個特定的條件判斷為false。一個do...while 陳述式看起來像以下:</code></p>
<pre class="syntaxbox">do
陳述式
while (條件式);
</pre>
<p><code>陳述式會在檢查條件式以前先執行一次。要執行多個陳述式的話,使用區塊陳述式來將那些陳述式歸為一組。如果條件式為true,那陳述式便再次執行。在每次執行的最後,條件會被檢查。當條件式為false時,</code> 停止執行並把控制傳給 <code>do...while接著的陳述式。</code></p>
<h3 id="範例_2"><strong>範例</strong></h3>
<p>在下列範例中,do迴圈重複了至少一次並不斷重複直到 i 不再比 5 少。</p>
<pre class="brush: js">var i = 0;
do {
i += 1;
console.log(i);
} while (i < 5);</pre>
<h2 id="while_陳述式"><code>while</code> 陳述式</h2>
<p><code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/while">while</a></code> 陳述式會不斷執行它的陳述式只要指定的條件式判斷為true。一個while陳述式看起來如下:</p>
<pre class="syntaxbox">while (condition)
statement
</pre>
<p>如果條件式變成 false ,在迴圈中的陳述式會停止執行並控制交給跟在這個迴圈後面的陳述式。</p>
<p>條件式的測試發生於迴圈內的陳述式執行之前。如果條件式傳回 true ,陳述式便會被執行而判斷式會再被測試一次。如果條件式傳回 false ,停止執行並把控制交給跟在 while 迴圈後面的陳述式。</p>
<p><code>要執行多個陳述式的話,使用區塊陳述式來將那些陳述式歸為一組。</code></p>
<h3 id="範例_1"><strong>範例 1</strong></h3>
<p>以下的while迴圈在只要n比3少的情況下便會不斷重複:</p>
<pre class="brush: js">var n = 0;
var x = 0;
while (n < 3) {
n++;
x += n;
}
</pre>
<p>在每次的疊代,迴圈把 n 遞增並將其值加到 x 上。因此,x 跟 n 的值會是下列情況:</p>
<ul>
<li>經過第一次迴圈後 <code>n</code> = 1 而 <code>x</code> = 1</li>
<li>經過第二次迴圈後 <code>n</code> = 2 而 <code>x</code> = 3</li>
<li>經過第三次迴圈後 <code>n</code> = 3 而 <code>x</code> = 6</li>
</ul>
<p>在完成第三次迴圈後,判斷是 n<3 不再是 true ,所以迴圈終止。</p>
<h3 id="範例_2_2"><strong>範例 2</strong></h3>
<p>避免無限迴圈。確定在迴圈內的判斷式終究會變成 false; 不然迴圈會永遠不終止。在迴圈內的陳述式會永遠的執行因為判斷式永遠不會變成false:</p>
<pre class="brush: js">while (true) {
console.log("Hello, world");
}</pre>
<h2 id="label_陳述式"><code>label</code> 陳述式</h2>
<p> <a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/label">label</a> 提供一個有識別字的陳述式讓你能在程式的別的地方參考。舉個例子,你能使用label 來識別一個迴圈,然後使用break或continue陳述式來指示何時程式該中斷迴圈或是繼續他的執行。</p>
<p>label 陳述式的語法看起來如下:</p>
<pre class="syntaxbox">label :
statement
</pre>
<p>Label的值可以是任何不是保留字的JavaScript識別字。你用label所識別的陳述式可以是任何陳述式。</p>
<h3 id="範例_3"><strong>範例</strong></h3>
<p>在這個範例,<code>markLoop這個label 識別一個while 迴圈。</code></p>
<pre class="brush: js">markLoop:
while (theMark == true) {
doSomething();
}</pre>
<h2 id="break_陳述式"><code>break</code> 陳述式</h2>
<p><code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/break">break</a></code> 陳述式是用來終止一個迴圈,一個switch多重控制選項,或是和一個label陳述式聯合使用。</p>
<ul>
<li>當你在沒有label的情況下使用break,它會馬上終止最內部的 while , do-while , for ,或是 switch 區間並將控制交給接下來的陳述式。</li>
<li>當你跟label一起使用的時候,它會終止那個特定的被label的陳述式。</li>
</ul>
<p>break 陳述式的語法看起來如下:</p>
<ol>
<li><code>break;</code></li>
<li><code>break <em>label</em>;</code></li>
</ol>
<p>第一種語法會終止最內部的迴圈或switch區間;第二種語法會終止那個特定的label陳述式。</p>
<h3 id="範例_1_2"><strong>範例</strong> <strong>1</strong></h3>
<p>以下的範例會不斷重複跑迴圈直到有在陣列裡的元素符合 theValue 的值:</p>
<pre class="brush: js">for (var i = 0; i < a.length; i++) {
if (a[i] == theValue) {
break;
}
}</pre>
<h3 id="範例_2_Break至一個label陳述式"><strong>範例 2: </strong>Break至一個label陳述式</h3>
<pre class="brush: js">var x = 0;
var z = 0;
labelCancelLoops: while (true) {
console.log("Outer loops: " + x);
x += 1;
z = 1;
while (true) {
console.log("Inner loops: " + z);
z += 1;
if (z === 10 && x === 10) {
break labelCancelLoops;
} else if (z === 10) {
break;
}
}
}
</pre>
<h2 id="continue_陳述式"><code>continue</code> 陳述式</h2>
<p><code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/continue">continue</a></code> 陳述式可以用於重新開始一個 while , do-while, for, 或 label 陳述式。</p>
<ul>
<li>當你在沒有label的情況下使用continue,它會終止現在最內部while, do-while , for陳述式區間的迭代並繼續執行該迴圈的下一個迭代。跟break陳述式不同的是,continue不會把整個迴圈的執行給終止。在while 迴圈中,它會跳回條件式的判斷。在for迴圈中,它會跳至遞增陳述式。</li>
<li>當contunue跟label一起使用的時候,它會應用至被label識別的那個迴圈陳述式。</li>
</ul>
<p>continue 陳述式的語法看起來如下:</p>
<ol>
<li><code>continue;</code></li>
<li><code>continue </code><em><code>label;</code></em></li>
</ol>
<h3 id="範例_1_3"><strong>範例 1</strong></h3>
<p>以下的範例有while迴圈以及一個在 i 的值為 3 的時候執行的continue陳述式。因此,n的值會連著是 1, 3, 7, 12。</p>
<pre class="brush: js">var i = 0;
var n = 0;
while (i < 5) {
i++;
if (i == 3) {
continue;
}
n += i;
}
</pre>
<h3 id="範例_2_3"><strong>範例 2</strong></h3>
<p>一個被label成 checkiandj 的陳述式包還著一個被label成 checkj 的陳述式。如果遇到了continue,程式會終止現在的這輪迴圈並開始下一輪。每次遇到continue,checkj就會一直重複直到它的條件式返回false。當false被傳回時,checkiandj 陳述式剩下的陳述式已被完成,而checkiandj 也會繼續重複直到它的條件式傳回 false。當false被傳回,程式會繼續進行接著checkiandj後面的陳述式。</p>
<p>如果continue有了checkiandj的label 程式會從checkiandj陳述式的頭開始繼續。</p>
<pre class="brush: js">checkiandj:
while (i < 4) {
console.log(i);
i += 1;
checkj:
while (j > 4) {
console.log(j);
j -= 1;
if ((j % 2) == 0) {
continue checkj;
}
console.log(j + " is odd.");
}
console.log("i = " + i);
console.log("j = " + j);
}</pre>
<h2 id="for...in_陳述式"><code>for...in</code> 陳述式</h2>
<p><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/for...in"><code>for...in</code></a> 陳述式重複一個指定的變數來循環一個物件所有可枚舉的屬性。至於每個獨特的屬性,JavaScript執行特定的陳述式。一個<code>for...in</code> 陳述式看起來像以下:</p>
<pre class="syntaxbox">for (variable in object) {
statements
}
</pre>
<h3 id="範例_4"><strong>範例</strong></h3>
<p>以下的函式透過它的參數得到一個物件和物件的名字。接著它循環這個物件的所有屬性並傳回一個列出屬性名和值的字串。</p>
<pre class="brush: js">function dump_props(obj, obj_name) {
var result = "";
for (var i in obj) {
result += obj_name + "." + i + " = " + obj[i] + "<br>";
}
result += "<hr>";
return result;
}
</pre>
<p>對於一個擁有make跟model屬性的物件 car來說,執行結果是:</p>
<pre class="brush: js">car.make = Ford
car.model = Mustang
</pre>
<h3 id="陣列"><strong>陣列</strong></h3>
<p>雖然用for...in來迭代 {{jsxref("Array")}} 元素很吸引人,但是它傳回的除了數字的索引之外還有可能是你自己定的屬性名。因此還是用帶有數字索引的傳統<code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/for">for</a>迴圈來迭帶一個陣列會比較好。因為如果你想改變陣列物件,比如增加屬性或是方法,</code><strong>for...in</strong> 陳述式迭代的是自定的屬性而不是陣列的元素。</p>
<h2 id="for...of_陳述式"><code>for...of</code> 陳述式</h2>
<p> <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/for...of">for...of</a></code> 陳述式在<a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Guide/iterable">iterable objects</a>(可迭代的物件)上建立了一個循環 (包含 {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, <a href="https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a>(參數) 物件 等等), 對每個獨特屬性的值使用一個準備被執行的有陳述式的自訂迭代掛勾。</p>
<pre class="syntaxbox">for (<em>variable</em> of <em>object</em>) {
<em>statement
</em>}</pre>
<p>下列的範例可看出<code>for...of</code> 迴圈跟 <code><a href="/zh-TW/docs/Web/JavaScript/Reference/Statements/for...in" title="en-US/docs/JavaScript/Reference/Statements/for...in">for...in</a></code> 迴圈的差別。 <code>for...in</code> 在屬性名字循環,而<code>for...of</code> 在屬性的值循環。</p>
<pre class="brush:js">let arr = [3, 5, 7];
arr.foo = "hello";
for (let i in arr) {
console.log(i); // logs "0", "1", "2", "foo"
}
for (let i of arr) {
console.log(i); // logs 3, 5, 7
}
</pre>
<p>{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</p>
|