diff options
Diffstat (limited to 'files/zh-cn/learn/javascript/building_blocks/looping_code/index.html')
| -rw-r--r-- | files/zh-cn/learn/javascript/building_blocks/looping_code/index.html | 781 |
1 files changed, 781 insertions, 0 deletions
diff --git a/files/zh-cn/learn/javascript/building_blocks/looping_code/index.html b/files/zh-cn/learn/javascript/building_blocks/looping_code/index.html new file mode 100644 index 0000000000..3fb1a217da --- /dev/null +++ b/files/zh-cn/learn/javascript/building_blocks/looping_code/index.html @@ -0,0 +1,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">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 { + 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> |
