uTools-Manuals/docs/javascript/Guide/Loops_and_iteration.html
2019-04-21 11:50:48 +08:00

318 lines
18 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<article id="wikiArticle">
<div> <div class="prevnext" style="text-align: right;">
<p><a href="Guide/Control_flow_and_error_handling" style="float: left;">« 上一页</a><a href="Guide/Functions">下一页 »</a></p>
</div></div>
<p class="summary">循环提供了一种快速和简单的方式去做一些重复的事。<a href="/en-US/docs/Web/JavaScript/Guide">JavaScript入门</a>的这个章节会介绍在JavaScript中存在哪些不同的迭代语句。</p>
<p>你可以把循环想成一种计算机化的游戏告诉某人在一个方向上走X步然后在另一个方向上走Y步例如“向东走5步”可以用一个循环来这样表达</p>
<pre><code class="language-javascript">var step;
for (step = 0; step &lt; 5; step++) {
// Runs 5 times, with values of step 0 through 4.
console.log('Walking east one step');
}
</code></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="#labeled_语句">labeled 语句</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="/en-US/docs/Web/JavaScript/Reference/Statements/for"><code>for循环</code></a>会一直重复执行直到指定的循环条件为fasle。 JavaScript的for循环和Java与C的for循环是很相似的。一个for语句是这个样子的</p>
<pre><code class="language-javascript">for ([initialExpression]; [condition]; [incrementExpression])
statement
</code></pre>
<p>当一个for循环执行的时候会发生以下事件</p>
<ol>
<li>如果有初始化表达式<code>initialExpression</code>,它将被执行。这个表达式通常会初始化一个或多个循环计数器,但语法上是允许一个任意复杂度的表达式的。这个表达式也可以声明变量。</li>
<li>计算<code>condition</code>表达式的值。如果<code>condition的值是</code>true循环中的statement会被执行。如果<code>condition</code>的值是falsefor循环终止。如果<code>condition表达式整个都被省略掉了</code>condition的值会被认为是true。</li>
<li><code> 循环中的 statement被执行。如果需要执行多条语句可以使用块</code> (<code>{ ... }</code>)<code>来包裹这些语句。</code></li>
<li>如果有更新表达式<code>incrementExpression</code>,执行它.</li>
<li>然后流程回到步骤2。</li>
</ol>
<h3 id="例子"><strong>例子</strong></h3>
<p>下面的函数包含一个含有for循环去计算一个滑动列表中被选中项目的个数一个 <a href="/zh-CN/docs/Web/HTML/Element/select" title="HTML &lt;select&gt; 元素表示一个控件,提供一个选项菜单:"><code>&lt;select&gt;</code></a> 元素允许选择多项。for循环声明了变量i并将它的初始值设为0。它检查i比 <code>&lt;select&gt;</code> 元素中的选项数量少执行了随后的if语句然后在每次完成循环以后i的值增加1。</p>
<pre><code class="language-html">&lt;form name="selectForm"&gt;
&lt;p&gt;
&lt;label for="musicTypes"&gt;Choose some music types, then click the button below:&lt;/label&gt;
&lt;select id="musicTypes" name="musicTypes" multiple="multiple"&gt;
&lt;option selected="selected"&gt;R&amp;B&lt;/option&gt;
&lt;option&gt;爵士&lt;/option&gt;
&lt;option&gt;布鲁斯&lt;/option&gt;
&lt;option&gt;新纪元&lt;/option&gt;
&lt;option&gt;古典&lt;/option&gt;
&lt;option&gt;歌剧&lt;/option&gt;
&lt;/select&gt;
&lt;/p&gt;
&lt;p&gt;&lt;input id="btn" type="button" value="选择了多少个选项?" /&gt;&lt;/p&gt;
&lt;/form&gt;
&lt;script&gt;
function howMany(selectObject) {
var numberSelected = 0;
for (var i = 0; i &lt; selectObject.options.length; i++) {
if (selectObject.options[i].selected) {
numberSelected++;
}
}
return numberSelected;
}
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
alert('选择选项的数量是: ' + howMany(document.selectForm.musicTypes))
});
&lt;/script&gt;
</code></pre>
<h2 id="do...while_语句"><code>do...while</code> 语句</h2>
<p><code><a href="Reference/Statements/do...while">do...while</a></code> 语句一直重复直到指定的条件求值得到假false。 一个 do...while 语句看起来像这样:</p>
<pre><code class="language-javascript">do
statement
while (condition);
</code></pre>
<p><code>statement</code> 在检查条件之间会执行一次。要执行多条语句(语句块),要使用块语句 ({ ... }) 包括起来。 如果 <code>condition</code> 为真true<code>statement</code> 将再次执行。 在每个执行的结尾会进行条件的检查。当 <code>condition</code> 为假false执行会停止并且把控制权交回给 do...while 后面的语句。</p>
<h3 id="例子_2"><strong>例子</strong></h3>
<p>在下面的例子中, 这个 do 循环将至少重复一次并且一直重复直到 <code>i</code> 不再小于 5。</p>
<pre><code class="language-javascript">do {
i += 1;
console.log(i);
} while (i &lt; 5);</code></pre>
<h2 id="while_语句"><code>while</code> 语句</h2>
<p>一个 <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a></code> 语句只要指定的条件求值为真true就会一直执行它的语句块。一个 while 语句看起来像这样:</p>
<pre><code class="language-javascript">while (condition)
statement
</code></pre>
<p>如果这个条件变为假,循环里的 <code>statement</code> 将会停止执行并把控制权交回给 while 语句后面的代码。</p>
<p>条件检测会在每次 <code>statement</code> 执行之前发生。如果条件返回为真, <code>statement</code> 会被执行并紧接着再次测试条件。如果条件返回为假,执行将停止并把控制权交回给 while 后面的语句。</p>
<p>要执行多条语句(语句块),要使用块语句 ({ ... }) 包括起来。</p>
<h3 id="例子_1"><strong>例子 1</strong></h3>
<p>下面的 while 循环只要 n 小于 3就会一直执行</p>
<pre><code class="language-javascript">var n = 0;
var x = 0;
while (n &lt; 3) {
n++;
x += n;
}
</code></pre>
<p>在每次循环里, n 会增加1并被加到 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 &lt; 3 结果不再为真,所以循环终止了。</p>
<h3 id="例子_2_2"><strong>例子 2</strong></h3>
<p>避免无穷循环(无限循环)。保证循环的条件结果最终会变成假;否则,循环永远不会停止。下面这个 while 循环会永远执行因为条件永远不会变成假:</p>
<pre><code class="language-javascript">while (true) {
console.log("Hello, world");
}</code></pre>
<h2 id="labeled_语句"><code>labeled</code> 语句</h2>
<p>一个 <a href="Reference/Statements/label">label</a> 提供了一个可以让你引用到您程序别的位置的标识符。例如,你可以用 label 标识一个循环, 然后使用 break 或者 continue 来指出程序是否该停止循环还是继续循环。</p>
<p>label 语句的语法看起来像这样:</p>
<pre><code class="language-javascript">label :
statement
</code></pre>
<p><code>label</code> 的值可以是任何的非保留字的 JavaScript 标识符, <code>statement 可以是任意你想要标识的语句(块)。</code></p>
<h3 id="例子_3"><strong>例子</strong></h3>
<p>在这个例子里,标记 <code>markLoop</code> 标识了一个 while 循环。</p>
<pre><code class="language-javascript">markLoop:
while (theMark == true) {
doSomething();
}</code></pre>
<p> </p>
<div>Label 语句:</div>
<div> Label: statement</div>
<div> 如: begin: for (var i = 0; i &lt; 10 ; i++ ){</div>
<div> alert(i);</div>
<div> }</div>
<div> </div>
<div>举一个比较典型的例子,看完后即明白 Label 的应用:(未添加 Label</div>
<pre><code class="language-javascript"> var num = 0;
for (var i = 0 ; i &lt; 10 ; i++){
for (var j = 0 ; j &lt; 10 ; j++){
if( i == 5 &amp;&amp; j == 5 ){
break;
}
num++;
}
}
alert(num); // 循环在 i 为5j 为5的时候跳出 j循环但会继续执行 i 循环,输出 95</code></pre>
<div> </div>
<div>对比使用了 Label 之后的程序:(添加 Label 后)</div>
<pre><code class="language-javascript"> var num = 0;
outPoint:
for (var i = 0 ; i &lt; 10 ; i++){
for (var j = 0 ; j &lt; 10 ; j++){
if( i == 5 &amp;&amp; j == 5 ){
break outPoint;
}
num++;
}
}
alert(num); // 循环在 i 为5j 为5的时候跳出双循环返回到outPoint层继续执行输出 55</code></pre>
<div> </div>
<div>对比使用了break、continue语句</div>
<div>
<pre><code class="language-javascript">  var num = 0;
  outPoint:
  for(var i = 0; i &lt; 10; i++)
  {
  for(var j = 0; j &lt; 10; j++)
  {
  if(i == 5 &amp;&amp; j == 5)
  {
  continue outPoint;
   }
   num++;
  }
  }
  alert(num); //95 </code></pre>
从alert(num)的值可以看出continue outPoint;语句的作用是跳出当前循环并跳转到outPoint标签下的for循环继续执行。</div>
<h2 id="break_语句"><code>break</code> 语句</h2>
<p>使用 <code><a href="Reference/Statements/break">break</a></code> 语句来终止循环,<code>switch</code> 或者是链接到 label 语句。</p>
<ul>
<li>当你使用不带 label 的 <code>break</code> 时, 它会立即终止当前所在的 <code>while</code><code>do-while</code><code>for</code>,或者 <code>switch</code> 并把控制权交回这些结构后面的语句。</li>
<li>当你使用带 label 的 <code>break</code>它会终止指定的标记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><code class="language-javascript">for (i = 0; i &lt; a.length; i++) {
if (a[i] == theValue) {
break;
}
}</code></pre>
<h3 id="例子_2_终止一个_label"><strong>例子 2: </strong>终止一个 label</h3>
<pre><code class="language-javascript">var x = 0;
var z = 0
labelCancelLoops: while (true) {
console.log("外部循环: " + x);
x += 1;
z = 1;
while (true) {
console.log("内部循环: " + z);
z += 1;
if (z === 10 &amp;&amp; x === 10) {
break labelCancelLoops;
} else if (z === 10) {
break;
}
}
}
</code></pre>
<h2 id="continue_语句"><code>continue</code> 语句</h2>
<p>这个 <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/continue">continue</a></code> 语句可以用来继续执行(跳过代码块的剩余部分并进入下一循环)一个 while do-while for 或者 label 语句。</p>
<ul>
<li>当你使用不带 label 的 <code>continue</code> 时, 它终止当前 whiledo-while或者 for 语句到结尾的这次的循环并且继续执行下一次循环。</li>
<li>当你使用带 label 的 <code>continue</code> 时, 它会应用被 label 标识的循环语句。</li>
</ul>
<p><code>continue</code> 的语法看起来像这样:</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>下面的例子展示了带有一个当 i 等于 3的 continue 语句的循环。 于是, n 取到的值是 1 3 7 12。不带有一个当 i 等于 3的 continue 语句的循环。 于是, n 取到的值是 1 3 6 1015。</p>
<pre><code class="language-javascript">var i = 0;
var n = 0;
while (i &lt; 5) {
i++;
if (i == 3) {
continue;
}
n += i;
console.log(n);
}
//1,3,7,12
</code></pre>
<pre><code class="language-javascript">var i = 0;
var n = 0;
while (i &lt; 5) {
i++;
if (i == 3) {
// continue;
}
n += i;
console.log(n);
}
// 1,3,6,10,15</code></pre>
<p> </p>
<h3 id="例子_2_3"><strong>例子 2</strong></h3>
<p>一个被标签为checkiandj 的语句包含了一个标签为checkj 的语句。如果遇到continue语句程序会结束当前chechj的迭代并开始下一轮的迭代。每次遇到continue语句checkj 语句会一直重复执行直到checkj语句的条件为false。. 当返回false后checkiandj的剩余语句将会执行checkiandj会一直执行指导checkiandj的条件为false。当checkiandj的返回值为false时将会执行checkiandj 的下面的语句。</p>
<p>如果 continue 有一个标记 checkiandj 程序将会从 checkiandj 语句块的顶部继续执行。</p>
<pre><code class="language-javascript">var i = 0;
var j = 10;
checkiandj:
while (i &lt; 4) {
console.log(i);
i += 1;
checkj:
while (j &gt; 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);
}</code></pre>
<h2 id="for...in_语句"><code>for...in</code> 语句</h2>
<p>这个 <a href="Reference/Statements/for...in"><code>for...in</code></a> 语句循环一个指定的变量来循环一个对象所有可枚举的属性。JavaScript 会为每一个不同的属性执行指定的语句。</p>
<pre><code class="language-javascript">for (variable in object) {
statements
}
</code></pre>
<h3 id="例子_4"><strong>例子</strong></h3>
<p>下面的函数通过它的参数得到一个对象和这个对象的名字。然后循环这个对象的所有属性并且返回一个列出属性名和该属性值的字符串。</p>
<pre><code class="language-javascript">function dump_props(obj, obj_name) {
var result = "";
for (var i in obj) {
result += obj_name + "." + i + " = " + obj[i] + "&lt;br&gt;";
}
result += "&lt;hr&gt;";
return result;
}
</code></pre>
<p>对于一个对象拥有 make 和 model 属性的 car 对象来说,执行结果是:</p>
<pre><code class="language-javascript">car.make = Ford
car.model = Mustang
</code></pre>
<h3 id="数组"><strong>数组</strong></h3>
<p>虽然用<strong>for...in</strong>来迭代<a href="Reference/Array" title="REDIRECT Array"><code>Array</code></a>元素很诱人,但是它返回的除了数字索引外还有可能是你自定义的属性名字。因此还是用带有数字索引的传统的<code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for</a></code> 循环来迭代一个数组比较好,因为如果你想改变数组对象,比如添加属性或者方法,<strong>for...in </strong>语句迭代的是 自定义的属性而不是数组的元素。</p>
<h2 id="for...of_statement"><code>for...of</code> statement</h2>
<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...of">for...of</a>语句在可迭代的对象上创建了一个循环</code>(包括<a href="Reference/Array" title="REDIRECT Array"><code>Array</code></a>, <a href="Reference/Map" title="此页面仍未被本地化, 期待您的翻译!"><code>Map</code></a>, <a href="Reference/Global_Objects/Set" title="Set 对象允许你存储任何类型的唯一值无论是原始值或者是对象引用。"><code>Set</code></a>, 参数对象( <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a> 等等) ,对值的每一个独特的属性调用一个将被执行的自定义的和语句挂钩的迭代。 </p>
<pre><code class="language-javascript">for (<em>variable</em> of <em>object</em>) {
<em>statement
</em>}
</code></pre>
<p>下面的这个例子展示了 <code>for...of 和</code> <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a> 两种循环语句之间的区别。与</code> <code>for...in</code> 循环遍历的结果是数组元素的下标不同的是, <code>for...of 遍历的结果是元素的值:</code></p>
<pre><code class="language-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" // 注意这里没有 hello
}
</code></pre>
<p></p><div class="prevnext" style="text-align: right;">
<p><a href="Guide/Control_flow_and_error_handling" style="float: left;">« 上一页</a><a href="Guide/Functions">下一页 »</a></p>
</div><p></p>
</article>