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
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
|
---
title: 循环吧代码
slug: learn/JavaScript/Building_blocks/Looping_code
tags:
- JavaScript
- break
- continue
- for
- while
- 初学者
- 学习
- 循环
translation_of: Learn/JavaScript/Building_blocks/Looping_code
---
<div>{{LearnSidebar}}</div>
<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</div>
<p class="summary">编程语言可以很迅速方便地帮我们完成一些重复性的任务,<font>从多个基本计算到几乎完成了很多类似工作的其他情况。现在</font><font>我们来看看处理这种需求的JavaScript中可用的循环结构。</font></p>
<table class="learn-box standard-table">
<tbody>
<tr>
<th scope="row">前提条件:</th>
<td>基本的电脑知识,对HTML与CSS有基本的了解,及已阅读: <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>(JS的入门).</td>
</tr>
<tr>
<th scope="row">目标:</th>
<td>学习如何在JS里面使用循环语句.</td>
</tr>
</tbody>
</table>
<h2 id="来一起循环">来一起循环</h2>
<p>循环,循环,循环. 就与这些:<a href="https://en.wikipedia.org/wiki/Froot_Loops">popular breakfast cereals</a>, <a href="https://en.wikipedia.org/wiki/Vertical_loop">roller coasters</a> and <a href="https://en.wikipedia.org/wiki/Loop_(music)">musical production</a>一样,类似存在于编程中.编程中的循环也是一直重复着去做一件事 - 此处循环便是编程中的术语.</p>
<p>让我们来想一下下图,这位农夫考虑为他的家庭做一周的食物计划,他或许就需要执行一段循环:</p>
<p><img alt="" src="https://raw.githubusercontent.com/agnoCJY/agno.github.io/master/loop_js-02-farm-cn.png" style="height: 563px; width: 900px;"><br>
</p>
<p>一段循环通常需要一个或多个条件:</p>
<ul>
<li><strong>一个开始条件,</strong>它被初始化为一个特定的值 - 这是循环的起点("开始:我没有食物”,上面)。</li>
<li><strong>一个结束条件,</strong>这是循环停止的标准 - 通常计数器达到一定值。 以上所说的“我有足够的食物”吗? 假设他需要10份食物来养活他的家人。</li>
<li><strong>一个迭代器,</strong>这通常在每个连续循环上递增少量的计数器,直到达到退出条件。 我们以前没有明确说明,但是我们可以考虑一下农民能够每小时收集2份食物。 每小时后,他收集的食物量增加了两倍,他检查他是否有足够的食物。 如果他已经达到10分(退出条件),他可以停止收集回家。</li>
</ul>
<p>在 {{glossary("伪代码")}} 中,这看起来就像下面这样:</p>
<pre>loop(food = 0; foodNeeded = 10) {
if (food = foodNeeded) {
exit loop;
// 我们有足够的食物了,回家吧。
} else {
food += 2; // 花一个小时多收集两个食物。
// 循环将会继续执行。
}
}</pre>
<p>所以需要的食物量定为10,农民目前的数量为0。在循环的每次迭代中,我们检查农民的食物量是否等于他需要的量。 如果是这样,我们可以退出循环。 如果没有,农民花一个小时收集两部分食物,循环再次运行。</p>
<h3 id="为何?"><font><font>为何?</font></font></h3>
<p>在这一点上,您可能会了解循环中的高级概念,但您可能会认为“好的,但是,这有助于我编写更好的JavaScript代码?” 正如我们前面所说,循环与所做的事情都是一样的,这对于快速完成重复任务是非常有用的。</p>
<p>通常,循环的每个连续迭代的代码将略有不同,这意味着您可以完成相同但略有不同的任务的全部负载 - 如果您有很多不同的计算要做, 做不同的一个,不一样的一个又一个!</p>
<p>让我们来看一个例子来完美地说明为什么循环是一件好事。 假设我们想在{{htmlelement("canvas")}}元素上绘制100个随机圆(按更新按钮一次又一次地运行示例以查看不同的随机集):</p>
<div class="hidden">
<h6 id="Hidden_code">Hidden code</h6>
<pre class="brush: html"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Random canvas circles</title>
<style>
html {
width: 100%;
height: inherit;
background: #ddd;
}
canvas {
display: block;
}
body {
margin: 0;
}
button {
position: absolute;
top: 5px;
left: 5px;
}
</style>
</head>
<body>
<button>Update</button>
<canvas></canvas>
<script>
var btn = document.querySelector('button');
var canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
var WIDTH = document.documentElement.clientWidth;
var HEIGHT = document.documentElement.clientHeight;
canvas.width = WIDTH;
canvas.height = HEIGHT;
function random(number) {
return Math.floor(Math.random()*number);
}
function draw() {
ctx.clearRect(0,0,WIDTH,HEIGHT);
for (var i = 0; i < 100; i++) {
ctx.beginPath();
ctx.fillStyle = 'rgba(255,0,0,0.5)';
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
ctx.fill();
}
}
btn.addEventListener('click',draw);
</script>
</body>
</html></pre>
</div>
<p>{{ EmbedLiveSample('Hidden_code', '100%', 400, "", "", "hide-codepen-jsfiddle") }}</p>
<p>您现在不需要理解所有代码,但我们来看看实际绘制100个圆的那部分代码:</p>
<pre class="brush: js">for (var i = 0; i < 100; i++) {
ctx.beginPath();
ctx.fillStyle = 'rgba(255,0,0,0.5)';
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
ctx.fill();
}
</pre>
<p> </p>
<ul>
<li><code>random()</code>,在前面的代码中定义过了,返回一个 <code>0</code> 到 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">x-1</span></font> 间的整数。</li>
<li><code>WIDTH</code> 和<code>HEIGHT</code> 浏览器内部窗口的宽度和高度。</li>
</ul>
<p> </p>
<p>您应该有一个基本的想法 - 我们使用一个循环来运行这个代码的100次迭代,其中每一个在页面上的随机位置绘制一个圆。 无论我们绘制100个圆,1000还是10,000,所需的代码量将是相同的。 只有一个数字必须改变。</p>
<p>如果我们在这里没有使用循环,我们必须为我们想要绘制的每个圆重复以下代码:</p>
<pre class="brush: js">ctx.beginPath();
ctx.fillStyle = 'rgba(255,0,0,0.5)';
ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);
ctx.fill();</pre>
<p>这将非常无聊而且很难维持高速。 循环真的相当好用。</p>
<h2 id="循环的标准">循环的标准</h2>
<p>我们开始探索一些特定的循环结构。 第一个,你会经常使用到它,for循环 - 以下为for循环的语法:</p>
<pre>for (initializer; exit-condition; final-expression) {
// code to run
}</pre>
<p><font><font>我们有:</font></font></p>
<ol>
<li><font><font>关键字</font></font><code>for</code><font><font>,后跟一些括号。</font></font></li>
<li><font><font>在括号内,我们有三个项目,以分号分隔:</font></font>
<ol>
<li><font><font>一个</font></font><strong>初始化器</strong><font><font> - 这通常是一个设置为一个数字的变量,它被递增来计算循环运行的次数。</font><font>它也有时被称为</font></font><strong>计数变量</strong><font><font>。</font></font></li>
<li><font><font>一个</font></font><strong>退出条件</strong><font><font> -如前面提到的,这个定义循环何时停止循环。</font><font>这通常是一个表现为比较运算符的表达式,用于查看退出条件是否已满足的测试。</font></font></li>
<li>一个<strong>最终条件</strong><font><font> -这总是被判断(或运行),每个循环已经通过一个完整的迭代消失时间。</font><font>它通常用于增加(或在某些情况下递减)计数器变量,使其更接近退出条件值。</font></font></li>
</ol>
</li>
<li><font><font>一些包含代码块的花括号 - 每次循环迭代时都会运行这个代码。</font></font></li>
</ol>
<p><font><font>我们来看一个真实的例子,所以我们可以看出这些做得更清楚。</font></font></p>
<pre class="brush: js">var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin'];
var info = 'My cats are called ';
var para = document.querySelector('p');
for (var i = 0; i < cats.length; i++) {
info += cats[i] + ', ';
}
para.textContent = info;</pre>
<p>这给我们以下输出:</p>
<div class="hidden">
<h6 id="Hidden_code_2">Hidden code 2</h6>
<pre class="brush: html"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Basic for loop example</title>
<style>
</style>
</head>
<body>
<p></p>
<script>
var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin'];
var info = 'My cats are called ';
var para = document.querySelector('p');
for (var i = 0; i < cats.length; i++) {
info += cats[i] + ', ';
}
para.textContent = info;
</script>
</body>
</html></pre>
</div>
<p>{{ EmbedLiveSample('Hidden_code_2', '100%', 60, "", "", "hide-codepen-jsfiddle") }}</p>
<div class="note">
<p><strong>注</strong>: 您可以<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for.html">在GitHub上找到这段示例代码</a>。 (也可以<a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for.html">在线运行</a>)。</p>
</div>
<p>这显示了一个循环用于迭代数组中的项目,并与每个项目进行一些操作 - JavaScript中非常常见的模式。 这里:</p>
<ol>
<li>迭代器<code>i</code>从0开始(<code>var i = 0</code>)。</li>
<li>循环将会一直运行直到它不再小于猫数组的长度。 这很重要 - 退出条件显示循环仍然运行的条件。 所以在这种情况下,<code><cats.length</code>仍然是真的,循环仍然运行。</li>
<li>在循环中,我们将当前的循环项(<code>cats[i]</code>是<code>cats[当前下标的任何东西]</code>)以及逗号和空格连接到<code>info</code>变量的末尾。 所以:
<ol>
<li>在第一次运行中,<code>i = 0</code>,所以<code>cats[0] +','将</code>被连接到<code>info("Bill")</code>上。</li>
<li>在第二次运行中,<code>i = 1</code>,所以<code>cats[1] +','</code>将被连接到<code>info("Jeff")</code>上。</li>
<li>等等。 每次循环运行后,1将被添加到i(i ++),然后进程将再次启动。</li>
</ol>
</li>
<li>当等于<code>cats.length</code>时,循环将停止,浏览器将移动到循环下面的下一个代码位。</li>
</ol>
<div class="note">
<p><strong>注</strong>: 我们将退出条件设为<code>< cats.length</code>,而不是<code><= cats.length</code>是因为计算机从0开始,而不是1 - 开始时<code>i</code>是0,并且逐步增加到i<code> = 4</code>(最后一个数组的索引)。 <code>cats.length</code>返回5,因为数组中有5个项目,但是我们不希望达到<code>i = 5</code>,因为这将返回未定义的最后一个项目(没有索引为5的数组项目)。 所以我们想要比<code>cats.length</code>(<code>i <</code>)少1,而不是<code>cats.length</code>(<code>i <=</code>)。</p>
</div>
<div class="note">
<p><strong>注</strong>: 退出条件的一个常见错误是使它们使用“等于”(<code>===</code>)而不是说“小于或等于”(<code><=</code>)。 如果我们想要运行我的循环到<code>i = 5</code>,退出条件将需要是<code>i <= cats.length</code>。如果我们设置为<code>i === cats.length</code>,循环将不会运行,因为在第一次循环迭代时 i 不等于5,所以循环会立即停止。</p>
</div>
<p>我们留下的一个小问题是最后的输出句子形式不是很好:</p>
<blockquote>
<p>My cats are called Bill, Jeff, Pete, Biggles, Jasmin,</p>
</blockquote>
<p>理想情况下,我们想改变最后循环迭代中的连接,以便在句子末尾没有逗号。 嗯,没问题 - 我们可以很高兴地在我们的for循环中插入一个条件来处理这种特殊情况:</p>
<pre class="brush: js">for (var i = 0; i < cats.length; i++) {
if (i === cats.length - 1) {
info += 'and ' + cats[i] + '.';
} else {
info += cats[i] + ', ';
}
}</pre>
<div class="note">
<p><strong>注</strong>: 您可以<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for-improved.html">在GitHub上找到这个例子</a>。(也可以<a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for-improved.html">在线运行</a>)</p>
</div>
<div class="warning">
<p><strong>重要:</strong> 使用<code>for</code>- 与所有循环一样,您必须确保初始化程序被迭代,以便最终达到退出条件。 如果没有,循环将永不停止,浏览器将强制它停止,否则会崩溃。 这被称为无限循环。</p>
</div>
<h2 id="使用break退出循环">使用break退出循环</h2>
<p>如果要在所有迭代完成之前退出循环,可以使用break语句。 当我们查看switch语句时,我们已经在上一篇文章中遇到过这样的情况 - 当switch语句中符合输入表达式的情况满足时,break语句立即退出switch语句并移动到代码之后。</p>
<p>与循环相同 - break语句将立即退出循环,并使浏览器移动到跟随它的任何代码。</p>
<p>说我们想搜索一系列联系人和电话号码,只返回我们想要找的号码? 首先,一些简单的HTML - 一个文本{{htmlelement("input")}},允许我们输入一个名称来搜索,一个{{htmlelement("button")}}元素来提交搜索,以及一个{{htmlelement ("p")}}元素显示结果:<br>
</p>
<pre class="brush: html"><label for="search">Search by contact name: </label>
<input id="search" type="text">
<button>Search</button>
<p></p></pre>
<p>然后是JavaScript:</p>
<pre class="brush: js">const contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975'];
const para = document.querySelector('p');
const input = document.querySelector('input');
const btn = document.querySelector('button');
btn.addEventListener('click', function() {
let searchName = input.value.toLowerCase();
input.value = '';
input.focus();
for (let i = 0; i < contacts.length; i++) {
let splitContact = contacts[i].split(':');
if (splitContact[0].toLowerCase() === searchName) {
para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.';
break;
} else if (i === contacts.length - 1) {
para.textContent = 'Contact not found.';
}
}
});</pre>
<div class="hidden">
<h6 id="Hidden_code_3">Hidden code 3</h6>
<pre class="brush: html"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple contact search example</title>
<style>
</style>
</head>
<body>
<label for="search">Search by contact name: </label>
<input id="search" type="text">
<button>Search</button>
<p></p>
<script>
var contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975'];
var para = document.querySelector('p');
var input = document.querySelector('input');
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
var searchName = input.value;
input.value = '';
input.focus();
for (var i = 0; i < contacts.length; i++) {
var splitContact = contacts[i].split(':');
if (splitContact[0] === searchName) {
para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.';
break;
} else if (i === contacts.length-1)
para.textContent = 'Contact not found.';
}
}
});
</script>
</body>
</html></pre>
</div>
<p>{{ EmbedLiveSample('Hidden_code_3', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p>
<ol>
<li>首先我们有一些变量定义 - 我们有一个联系信息数组,每个项目是一个字符串,包含一个以冒号分隔的名称和电话号码。</li>
<li>接下来,我们将一个事件监听器附加到按钮(<code>btn</code>)上,这样当按下它时,运行一些代码来执行搜索并返回结果。</li>
<li>我们将输入的值输入到一个名为<code>searchName</code>的变量中,然后清空文本输入并重新对准它,准备进行下一个搜索。</li>
<li>现在有趣的部分,for循环:
<ol>
<li>我们的计数器开始时为在0,直到计数器不再小于<code>contacts.length</code>,并在循环的每次迭代之后将<code>i</code>递增1。</li>
<li>在循环中,我们首先将当前联系人(<code>contacts [i]</code>)拆分为冒号字符,并将生成的两个值存储在名为<code>splitContact</code>的数组中。</li>
<li>然后,我们使用条件语句来测试<code>splitContact [0]</code>(联系人姓名)是否等于输入的<code>searchName</code>。 如果是,我们在段落中输入一个字符串来报告联系人的号码,并使用break来结束循环。</li>
</ol>
</li>
<li>在<code>(contacts.length-1)</code> 迭代后,如果联系人姓名与输入的搜索不符,则段落文本设置为“未找到联系人”,循环继续迭代。</li>
</ol>
<div class="note">
<p><strong>注:</strong>您可以<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/contact-search.html">在GitHub上找到这个例子</a>或<a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/contact-search.html">在线运行</a>。</p>
</div>
<h2 id="使用continue跳过迭代">使用continue跳过迭代</h2>
<p>continue语句以类似的方式工作,而不是完全跳出循环,而是跳过当前循环而执行下一个循环。 我们来看另外一个例子,它把一个数字作为一个输入,并且只返回开平方之后为整数的数字(整数)。</p>
<p>HTML与最后一个例子基本相同 - 一个简单的文本输入和一个输出段落。 JavaScript也是一样的,虽然循环本身有点不同:</p>
<pre class="brush: js">var num = input.value;
for (var i = 1; i <= num; i++) {
var sqRoot = Math.sqrt(i);
if (Math.floor(sqRoot) !== sqRoot) {
continue;
}
para.textContent += i + ' ';
}</pre>
<p>Here's the output:</p>
<div class="hidden">
<h6 id="Hidden_code_4">Hidden code 4</h6>
<pre class="brush: html"><!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Integer squares generator</title>
<style>
</style>
</head>
<body>
<label for="number">Enter number: </label>
<input id="number" type="text">
<button>Generate integer squares</button>
<p>Output: </p>
<script>
var para = document.querySelector('p');
var input = document.querySelector('input');
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
para.textContent = 'Output: ';
var num = input.value;
input.value = '';
input.focus();
for (var i = 1; i <= num; i++) {
var sqRoot = Math.sqrt(i);
if (Math.floor(sqRoot) !== sqRoot) {
continue;
}
para.textContent += i + ' ';
}
});
</script>
</body>
</html></pre>
</div>
<p>{{ EmbedLiveSample('Hidden_code_4', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p>
<ol>
<li>在这种情况下,输入应为数字(<code>num</code>)。 for循环给定一个从1开始的计数器(在这种情况下,我们对0不感兴趣),一个退出条件,当计数器大于输入<code>num</code>时循环将停止,并且迭代器的计数器将每次增加1。</li>
<li>在循环中,我们使用<code>Math.sqrt(i)</code>找到每个数字的平方根,然后测试平方根是否是一个整数,通过判断当它被向下取整时,它是否与自身相同(这是<code>Math.floor(...)</code>对传递的数字的作用)。</li>
<li>如果平方根和四舍五入的平方根不相等(<code>!==</code>),则表示平方根不是整数,因此我们对此不感兴趣。 在这种情况下,我们使用continue语句跳过当前循环而执行下一个循环迭代,而不在任何地方记录该数字。</li>
<li>如果平方根是一个整数,我们完全跳过if块,所以continue语句不被执行; 相反,我们将当前i值加上一个空格连接到段落内容的末尾。</li>
</ol>
<div class="note">
<p><strong>注:</strong>您可以<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/integer-squares.html">在GitHub上查看完整代码</a>,或者<a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/integer-squares.html">在线运行</a>。</p>
</div>
<h2 id="while语句和do_..._while语句">while语句和do ... while语句</h2>
<p><code>for</code> 不是JavaScript中唯一可用的循环类型。 实际上还有很多其他的,而现在你不需要理解所有这些,所以值得看几个人的结构,这样你就可以在稍微不同的方式识别出相同的功能。</p>
<p>首先,我们来看看while循环。 这个循环的语法如下所示:</p>
<pre>initializer
while (exit-condition) {
// code to run
final-expression
}</pre>
<p>除了在循环之前设置初始化器变量,并且在运行代码之后,循环中包含final-expression,而不是这两个项目被包含在括号中,这与以前的for循环非常类似。 退出条件包含在括号内,前面是while关键字而不是for。</p>
<p>同样的三个项目仍然存在,它们仍然以与for循环中相同的顺序定义 - 这是有道理的,因为您必须先定义一个初始化器,然后才能检查它是否已到达退出条件; 在循环中的代码运行(迭代已经完成)之后,运行最后的条件,这只有在尚未达到退出条件时才会发生。</p>
<p>我们再来看看我们的猫列表示例,但是重写了一个while循环:</p>
<pre class="brush: js">var i = 0;
while (i < cats.length) {
if (i === cats.length - 1) {
info += 'and ' + cats[i] + '.';
} else {
info += cats[i] + ', ';
}
i++;
}</pre>
<div class="note">
<p><strong>Note</strong>: This still works just the same as expected — have a look at it <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/while.html">running live on GitHub</a> (also view the <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/while.html">full source code</a>).</p>
</div>
<p><a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a>循环非常类似但在while后提供了终止条件:</p>
<pre>initializer
do {
// code to run
final-expression
} while (exit-condition)</pre>
<p>在这种情况下,在循环开始之前,初始化程序先重新开始。 do关键字直接在包含要运行的代码的花括号和终止条件之前。</p>
<p>这里的区别在于退出条件是一切都包含在括号中,而后面是一个while关键字。 在do ... while循环中,花括号中的代码总是在检查之前运行一次,以查看是否应该再次执行(在while和for中,检查首先出现,因此代码可能永远不会执行)。</p>
<p>我们再次重写我们的猫列表示例,以使用do...while循环:</p>
<pre class="brush: js">var i = 0;
do {
if (i === cats.length - 1) {
info += 'and ' + cats[i] + '.';
} else {
info += cats[i] + ', ';
}
i++;
} while (i < cats.length);</pre>
<div class="note">
<p><strong>Note</strong>: 再一次,它正如我们期望的那样工作 — 看一看它在<a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/do-while.html">Github在线运行</a> (或者查看<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/do-while.html">完整源代码</a>).</p>
</div>
<div class="warning">
<p><strong>Important</strong>: 使用 while 和 do...while — 所有循环都一样 — 你必须保证初始变量是迭代的,那么它才会逐渐地达到退出条件. 不然, 它将会永远循环下去, 要么浏览器会强制终止它,要么它自己会崩溃. 这称为无限循环.</p>
</div>
<h2 id="主动学习:启动倒计时!">主动学习:启动倒计时!</h2>
<p>在这个练习中,我们希望你打印出一个简单的启动倒计时到输出框,从10到关闭。 具体来说,我们希望你:</p>
<ul>
<li>从10下降到0.我们为您提供了一个初始化器 - var i = 10;</li>
<li>对于每次迭代,创建一个新的段落并将其附加到输出<div>,我们使用<code>var output = document.querySelector('.output');</code>。在评论中,我们为您提供了需要在循环中某处使用的三条代码行:
<ul>
<li><code>var para = document.createElement('p');</code> —新建一个段落。</li>
<li><code>output.appendChild(para);</code> — 将段落附加到输出 <code><div></code>中。</li>
<li><code>para.textContent =</code> — 段落内的文字等于您放在右侧的任何内容。</li>
</ul>
</li>
<li>不同的迭代数字需要将不同的文本放在该迭代的段落中(您需要一个条件语句和多个<code>para.textContent = lines</code>):
<ul>
<li>如果数字是10,打印“Countdown 10”到段落。</li>
<li>如果数字为0,请打印“Blast off!” 到段落。</li>
<li>对于任何其他数字,只打印段落的数字。</li>
</ul>
</li>
<li>记住要包括一个迭代器! 然而,在这个例子中,我们在每次迭代之后都下降,而不是上升,所以你不想要<code>i++</code> - 你如何向下迭代?</li>
</ul>
<p>如果您犯了错误,您可以随时使用“重置”按钮重置该示例。 如果你真的卡住了,请按“显示解决方案”来查看解决方案。</p>
<div class="hidden">
<h6 id="Active_learning">Active learning</h6>
<pre class="brush: html"><div class="output" style="height: 410px;overflow: auto;">
</div>
<textarea id="code" class="playable-code" style="height: 300px;">
var output = document.querySelector('.output');
output.innerHTML = '';
// var i = 10;
// var para = document.createElement('p');
// para.textContent = ;
// output.appendChild(para);
</textarea>
<div class="playable-buttons">
<input id="reset" type="button" value="Reset">
<input id="solution" type="button" value="Show solution">
</div>
</pre>
<pre class="brush: js">var textarea = document.getElementById('code');
var reset = document.getElementById('reset');
var solution = document.getElementById('solution');
var code = textarea.value;
function updateCode() {
eval(textarea.value);
}
reset.addEventListener('click', function() {
textarea.value = code;
updateCode();
});
solution.addEventListener('click', function() {
textarea.value = jsSolution;
updateCode();
});
var jsSolution = 'var output = document.querySelector(\'.output\');\noutput.innerHTML = \'\';\n\nvar i = 10;\n\nwhile(i >= 0) {\n var para = document.createElement(\'p\');\n if(i === 10) {\n para.textContent = \'Countdown \' + i;\n } else if(i === 0) {\n para.textContent = \'Blast off!\';\n } else {\n para.textContent = i;\n }\n\n output.appendChild(para);\n\n i--;\n}';
textarea.addEventListener('input', updateCode);
window.addEventListener('load', updateCode);
</pre>
</div>
<p>{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}</p>
<h2 id="主动学习:填写来宾列表">主动学习:填写来宾列表</h2>
<p>在本练习中,我们希望您获取存储在数组中的名称列表,并将其放入来宾列表中。 但这不是那么容易 - 我们不想让菲尔和洛拉进来,因为他们是贪婪和粗鲁的,总是吃所有的食物! 我们有两个名单,一个是客人承认的,一个是客人拒绝的。</p>
<p>具体来说,我们希望你:</p>
<ul>
<li>编写一个循环,它将从0迭代到people数组的长度。 你需要从一个初始化器<code>var i = 0</code>开始,但是你需要什么退出条件?</li>
<li>在每个循环迭代期间,使用条件语句检查当前数组项是否等于“Phil”或“Lola”:
<ul>
<li>如果是,则将数组项连接到拒绝段落的<code>textContent</code>的末尾,后跟逗号和空格。</li>
<li>如果不是,则将数组项连接到接收段落的<code>textContent</code>的末尾,后跟逗号和空格。</li>
</ul>
</li>
</ul>
<p>我们已经提供给您:</p>
<ul>
<li><code>var i = 0;</code> — 你的初始化程序</li>
<li><code>refused.textContent +=</code> - 将连接某些东西的行的开头,结束于<code>refused.textContent</code>。</li>
<li><code>admitted.textContent +=</code> - 将连接某些内容到一行的结尾的行的开始。</li>
</ul>
<p>额外的奖金问题 - 成功完成上述任务后,您将留下两个名称列表,用逗号分隔,但它们将不整齐 - 每个结尾处都会有一个逗号。 你可以制定出如何在每种情况下编写最后一个逗号的行,并添加一个完整的停止? 看看有用的字符串方法文章的帮助。</p>
<p>如果您犯了错误,您可以随时使用“重置”按钮重置该示例。 如果你真的卡住了,请按“显示解决方案”来查看解决方案。</p>
<div class="hidden">
<h6 id="Active_learning_2">Active learning 2</h6>
<pre class="brush: html"><div class="output" style="height: 100px;overflow: auto;">
<p class="admitted">Admit: </p>
<p class="refused">Refuse: </p>
</div>
<textarea id="code" class="playable-code" style="height: 400px;">
var people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce'];
var admitted = document.querySelector('.admitted');
var refused = document.querySelector('.refused');
admitted.textContent = 'Admit: ';
refused.textContent = 'Refuse: '
// var i = 0;
// refused.textContent += ;
// admitted.textContent += ;
</textarea>
<div class="playable-buttons">
<input id="reset" type="button" value="Reset">
<input id="solution" type="button" value="Show solution">
</div>
</pre>
<pre class="brush: js">var textarea = document.getElementById('code');
var reset = document.getElementById('reset');
var solution = document.getElementById('solution');
var code = textarea.value;
function updateCode() {
eval(textarea.value);
}
reset.addEventListener('click', function() {
textarea.value = code;
updateCode();
});
solution.addEventListener('click', function() {
textarea.value = jsSolution;
updateCode();
});
var jsSolution = 'var people = [\'Chris\', \'Anne\', \'Colin\', \'Terri\', \'Phil\', \'Lola\', \'Sam\', \'Kay\', \'Bruce\'];\n\nvar admitted = document.querySelector(\'.admitted\');\nvar refused = document.querySelector(\'.refused\');\n\nvar i = 0;\n\ndo {\n if(people[i] === \'Phil\' || people[i] === \'Lola\') {\n refused.textContent += people[i] + \', \';\n } else {\n admitted.textContent += people[i] + \', \';\n }\n i++;\n} while(i < people.length);\n\nrefused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + \'.\';\nadmitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + \'.\';';
textarea.addEventListener('input', updateCode);
window.addEventListener('load', updateCode);
</pre>
</div>
<p>{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }}</p>
<h2 id="应该使用哪种循环类型?">应该使用哪种循环类型?</h2>
<p>对于基本用途,for,while和do ... while循环大部分可互换。 他们都可以用来解决相同的问题,你使用哪一个将在很大程度上取决于你的个人偏好 - 哪一个你最容易记住或最直观的。 我们再来看看他们。</p>
<p>首先是 <code>for</code>:</p>
<pre>for (initializer; exit-condition; final-expression) {
// code to run
}</pre>
<p><code>while</code>:</p>
<pre>initializer
while (exit-condition) {
// code to run
final-expression
}</pre>
<p>最后是 <code>do...while</code>:</p>
<pre>initializer
do {
// code to run
final-expression
} while (exit-condition)</pre>
<p>我们建议使用<code>for</code>,因为它可能是最简单地帮你记住一切 - 初始化程序,退出条件和最终表达式都必须整齐地放入括号,所以很容易看到他们在哪里并检查你没有丢失他们。</p>
<div class="note">
<p><strong>注:</strong>还有其他循环类型/特性,这些特性在 高级/专门 的情况下是有用的,超出了本文的范围。如果您想进一步了解循环学习,请阅读我们的高级<a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">循环和迭代指南</a>。</p>
</div>
<h2 id="结论">结论</h2>
<p>本文向您展示了背后的基本概念,以及JavaScript中循环代码时可用的不同选项。 你现在应该明白为什么循环是一个处理重复代码的好机制,并且在你自己的例子中使用它们!</p>
<p>如果您有什么不明白的地方,可以再通读一遍,或者<a href="/en-US/Learn#Contact_us">联系我们</a>寻求帮助。</p>
<h2 id="相关链接">相关链接</h2>
<ul>
<li><a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Loops and iteration in detail</a></li>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for statement reference</a></li>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> references</li>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/break">break</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/continue">continue</a> references</li>
<li>
<p class="entry-title"><a href="https://www.impressivewebs.com/javascript-for-loop/">What’s the Best Way to Write a JavaScript For Loop?</a> — some advanced loop best practices</p>
</li>
</ul>
<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</p>
<p> </p>
<h2 id="在本单元中">在本单元中</h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li>
</ul>
<p> </p>
|