diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/ja/learn/javascript/building_blocks/looping_code | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/ja/learn/javascript/building_blocks/looping_code')
-rw-r--r-- | files/ja/learn/javascript/building_blocks/looping_code/index.html | 933 |
1 files changed, 933 insertions, 0 deletions
diff --git a/files/ja/learn/javascript/building_blocks/looping_code/index.html b/files/ja/learn/javascript/building_blocks/looping_code/index.html new file mode 100644 index 0000000000..dd5e724fca --- /dev/null +++ b/files/ja/learn/javascript/building_blocks/looping_code/index.html @@ -0,0 +1,933 @@ +--- +title: ループコード +slug: Learn/JavaScript/Building_blocks/Looping_code +tags: + - Article + - Beginner + - CodingScripting + - DO + - Guide + - JavaScript + - Learn + - Loop + - break + - continue + - for + - 'l10n:priority' + - 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">プログラミング言語は、繰り返し実行するタスクを素早く終わらせるのがとても得意です。基本的な計算処理から、同じような作業がたくさんあるのならどんな状況でもこなします。今度は JavaScript でそういった目的を果たすために使用するループ構造を見てみましょう。</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">前提条件:</th> + <td>基本的なコンピューターの知識および HTML と CSS への理解、<a href="https://developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps">JavaScript の第一歩</a>。</td> + </tr> + <tr> + <th scope="row">目的:</th> + <td>JavaScript でループの使い方を理解する。</td> + </tr> + </tbody> +</table> + +<h2 id="Keep_me_in_the_loop" name="Keep_me_in_the_loop">ループの中にとどまる</h2> + +<p>ループ、ループ、ループ。<a href="https://en.wikipedia.org/wiki/Froot_Loops">朝食用シリアル</a>や、<a href="https://en.wikipedia.org/wiki/Vertical_loop">ジェットコースター</a>、<a href="https://en.wikipedia.org/wiki/Loop_(music)">音楽</a>でもおなじみですが、プログラミングにおいても、とても重要な概念です。プログラミングにおけるループとは同じことを何度も何度も繰り返すことで、<strong>反復</strong>や<strong>繰り返し</strong>とも言われます。</p> + +<p>それでは、農家のケースについて考えてみましょう。彼は家族を養うため十分な食料があるか確認しようとしています。それを実現するため、以下のようなループを使用するでしょう。</p> + +<p><br> + <img alt="" src="https://mdn.mozillademos.org/files/13755/loop_js-02-farm.png" style="display: block; margin: 0px auto;"></p> + +<p>ループにはたいてい以下のような機能があります。</p> + +<ul> + <li><strong>カウンター:</strong> ループの開始地点で、初期化される値です。(上記の絵の、"I have no food" [食料がない] の部分です)。</li> + <li><strong>条件:</strong> ループの実行を継続するか終了するかを決める true/false の判定です。たいていはカウンターがある値に達した場合に終了します。上記の絵の、"Do I have enough food?" [十分な食料があるか?] の部分です。例えば、家族に食べさせる 10 個の食料が必要である、というようなことです。</li> + <li><strong>イテレーター:</strong> これは一般的には条件が <code>true</code>. では無くなるまで、カウンターの値をループごとに少量ずつ増加させます。上記の絵には明示的には描いていませんが、農家が 1 時間に 2 つの食料を集めることができると考えるとします。この場合、1 時間ごとに 2 つずつ食料が増えていき、農家は十分な食料が集まったかを確認することができます。もし食料が 10 個になったら (条件が true では無くなったため、ループが終了するポイント)、集めるのをやめて家に帰ることができるでしょう。</li> +</ul> + +<p>{{glossary("pseudocode", "疑似コード")}}では、以下のようになるでしょう。</p> + +<pre class="notranslate">loop(food = 0; foodNeeded = 10) { + if (food >= foodNeeded) { + exit loop; + // 十分な食料が集まりました。家に帰りましょう + } else { + food += 2; // 1 時間経って 2 つの食料を集めました + // ループはさらに続きます + } +}</pre> + +<p>最初に、必要な食料が 10 に設定され、農家が現在持っている食料は 0 に設定されます。ループの繰り返しごとに、農家の持っている食料が必要な食料の数に等しいかを調べています。もしそうであれば、ループを抜けられます。そうでなければ、農家は 1 時間ごとに 2 つの食料を集めるのを繰り返します。</p> + +<h3 id="Why_bother" name="Why_bother">どうしてこんなことをするの?</h3> + +<p>これで、恐らくループの背後にあるコンセプトが理解できたことでしょう。けれど、「それが JavaScript のコードを書くのにどう役立つの?」と思っているかもしれませんね。先ほど<strong>ループは同じことを繰り返すこと</strong>だと言いいましたが、それは<strong>素早く繰り返し同じ作業を完了させる</strong>のに最適なことなのです。</p> + +<p>たいてい、コードはループの連続する反復のたびごとにわずかに異なるものになります。つまり、似ているけれどわずかに異なる多数のタスク全体を完了出来るのです。もしたくさんの異なる計算をしなければならないとしたら、同じことを何度も何度もするのではなく、それぞれ異なることをしたいですよね。</p> + +<p>ループがどれだけ素晴らしいものかを説明する例を見てみましょう。100 個のランダムな円を {{htmlelement("canvas")}} 要素に描きたいとします (<em>更新</em>ボタンを押して、例を何度となく実行し、結果が異なることを見てみましょう。)</p> + +<div class="hidden"> +<h6 id="Hidden_code" name="Hidden_code">Hidden code</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>キャンバスに描くランダムな円</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>更新</button> + + <canvas></canvas> + + + <script> + const btn = document.querySelector('button'); + const canvas = document.querySelector('canvas'); + const ctx = canvas.getContext('2d'); + + let WIDTH = document.documentElement.clientWidth; + let 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 (let 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 notranslate">for (let 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> + +<ul> + <li><code>random(x)</code> はコードの前半で定義され、<code>0</code> から <code>x-1</code> までの整数を返します</li> + <li><code>WIDTH</code> と <code>HEIGHT</code> は、内側のブラウザーウィンドウの幅と高さです。</li> +</ul> + +<p>基本的な考えがわかりましたか?このコードをループを使用して 100 回実行しますが、毎回ページ内のランダムな場所に円を描いています。必要なコードは 100 個の円を描くときも、1000 個でも 10,000 個でも同じです。1 か所だけ変更すればいいのです。</p> + +<p>ここでループを使用しないとすれば、次のコードを描きたい数だけ繰り返し書かなければなりません。</p> + +<pre class="brush: js notranslate">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="The_standard_for_loop" name="The_standard_for_loop">標準的な for ループ</h2> + +<p>ここからは、具体的なループの構造を見ていきましょう。最初は、特によく使うことになるであろう <a href="/ja/docs/Web/JavaScript/Reference/Statements/for">for</a> ループについてです。構文は以下の通りです。</p> + +<pre class="notranslate">for (初期化処理; 条件; 最後の式) { + // 実行するコード +}</pre> + +<p>ここでは...</p> + +<ol> + <li><code>for</code> キーワードに続き括弧があります。</li> + <li>括弧の中にはセミコロンで区切られて以下の項目があります。 + <ol> + <li><strong>初期化処理</strong>: これはたいていの場合、繰り返し回数分増やしていく変数の初期化処理となります。この変数を<strong>カウンター変数</strong>と呼ぶことがあります。</li> + <li><strong>条件</strong>: 既に取り上げた通り、これはループが繰り返しをやめるべき条件を定義します。ほとんどの場合は比較演算子を伴って、終了条件を満たしているかを判定します。</li> + <li><strong>最後の式</strong>: これはループの 1 回が終了する度に評価される (または実行される) コードです。大体、カウンター変数を増やし(または減らし)、条件が <code>true</code> では無くなるポイントに近づけていきます。</li> + </ol> + </li> + <li>そして中括弧があり、中括弧の中のコードブロックが各ループの繰り返しで実行されます。</li> +</ol> + +<p>それでは実際の例を見て、これらを明確に分かるようにしてみましょう。</p> + +<pre class="brush: js notranslate">const cats = ['ビル', 'ジェフ', 'ピート', 'ビッグルズ', 'ジャスミン']; +let info = '私の猫の名前は、'; +const para = document.querySelector('p'); + +for (let i = 0; i < cats.length; i++) { + info += cats[i] + '、'; +} + +para.textContent = info;</pre> + +<p>これで次の結果が得られます。</p> + +<div class="hidden"> +<h6 id="Hidden_code_2" name="Hidden_code_2">Hidden code 2</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>for ループの例</title> + <style> + + </style> + </head> + <body> + + <p></p> + + + <script> + const cats = ['ビル', 'ジェフ', 'ピート', 'ビッグルズ', 'ジャスミン']; + let info = '私の猫の名前は、'; + const para = document.querySelector('p'); + + for (let 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> をカウンター変数(イニシャライザーやイテレーター変数ともいう)として、<code>0</code> から開始します (<code>let i = 0</code>)。</li> + <li><code>i</code> が <code>cats</code> 配列の長さより小さくなくなるまで実行すると、ループには指定されています。これは重要です、条件にはループが継続するための条件が示されています。今回は、<code>i < cats.length</code> が真となるため、ループは継続します。</li> + <li>ループの内側では、現在繰り返し対象となる項目 (<code>cats[i]</code> は <code>cats[i に入っているそのときの値]</code> となります) を <code>info</code> 変数に対してカンマとスペースとともに結合しています。つまり... + <ol> + <li>初回の実行時には、<code>i = 0</code> なので <code>cats[0] + ', '</code> ("ビル、") が <code>info</code> に対して結合されます。</li> + <li>2 回目の実行時には、<code>i = 1</code> なので <code>cats[1] + ', '</code> ("ジェフ、") が <code>info</code> に対して結合されます。</li> + <li>このように、ループ内の処理が実行されるたび、1 が <code>i</code> に加算され (<code>i++</code>)、次の処理が開始されます。</li> + </ol> + </li> + <li><code>i</code> が <code>cats.length</code> の値 (ここでは 5) と等しくなったときにループは終了し、ブラウザーはループの後に続くコードを実行します。</li> +</ol> + +<div class="note"> +<p><strong>注</strong>: 条件を <code>i <= cats.length</code> ではなく、<code>i < cats.length</code> としているのは、コンピューターが数値を 1 からではなく、0 から数えるためです。コードでも <code>i</code> を <code>0</code> から始め、<code>i = 4</code> (配列内の要素の最後のインデックス) となるまで加算していきます。配列内の要素が 5 つなので <code>cats.length</code> は 5 となりますが、<code>i = 5</code> とすると、(配列に 5 のインデックスの要素がないので) <code>undefined</code> となってしまいます。なので、<code>cats.length</code> と同じ値まで (<code>i <=</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> と指定した場合、ループは 1 度も実行されずに終了してしまいます。なぜなら、ループの最初では <code>i</code> が <code>5</code> ではないため、そこで終わってしまうからです。</p> +</div> + +<p>残る小さな問題は、出力された文が完全ではないことです。</p> + +<blockquote> +<p>私の猫の名前は、ビル、ジェフ、ピート、ビッグルズ、ジャスミン、</p> +</blockquote> + +<p>ループの最後の結合処理を変更して文の最後が「、」で終わらないようにしたいと思います。まったく問題ありません。ループの中に条件ブロックを挿入して、これに対処しましょう。</p> + +<pre class="brush: js notranslate">for (let i = 0; i < cats.length; i++) { + if (i === cats.length - 1) { + info += 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>: for ループ (他のループも同様) では、カウンター変数を増加、もしくは場合により減少させて、最終的に条件が true では無くなるポイントに達するようにする必要があります。もしそうで無い場合、ループは永遠に回り続け、ブラウザーが強制的に停止するか、クラッシュしてしまうでしょう。これは<strong>無限ループ</strong>といいます。</p> +</div> + +<h2 id="Exiting_loops_with_break" name="Exiting_loops_with_break">break でループを終了する</h2> + +<p>すべての繰り返し処理が終了する前にループを終了したいとき、<a href="/ja/docs/Web/JavaScript/Reference/Statements/break">break</a> 文を使用して終了させることができます。前回の記事、<a href="/ja/Learn/JavaScript/Building_blocks/conditionals#switch_statements">switch 文</a>で、入力した値が switch 文の case にマッチしたとき、switch 文を抜け、それ以降のコードを実行するために <code>break</code> 文を使用しました。 </p> + +<p>これはループでも同様で、<code>break</code> 文を使用することで即時にループを抜けて、ブラウザーに続きのコードを実行させることができます。</p> + +<p>それでは、連絡先 (電話番号を持っている) の配列の中から特定の連絡先を検索してみましょう。まずは HTML です。検索するテキスト入力用の {{htmlelement("input")}} 要素と、検索内容を送信 (submit) する {{htmlelement("button")}} 要素、検索結果を表示する {{htmlelement("p")}} 要素を備えます。</p> + +<pre class="brush: html notranslate"><label for="search">連絡先の名前: </label> +<input id="search" type="text"> +<button>検索</button> + +<p></p></pre> + +<p>現在の JavaScript について:</p> + +<pre class="brush: js notranslate">const contacts = ['クリス:2232322', 'サラ:3453456', 'ビル:7654322', 'メアリー:9998769', 'ダイアン: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] + ' の電話番号は ' + splitContact[1] + ' です。'; + break; + } else { + para.textContent = '連絡先が見つかりません。'; + } + } +});</pre> + +<div class="hidden"> +<h6 id="Hidden_code_3" name="Hidden_code_3">Hidden code 3</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>連絡先検索の例</title> + <style> + + </style> + </head> + <body> + + <label for="search">連絡先の名前: </label> + <input id="search" type="text"> + <button>検索</button> + + <p></p> + + + <script> + const contacts = ['クリス:2232322', 'サラ:3453456', 'ビル:7654322', 'メアリー:9998769', 'ダイアン:9384975']; + const para = document.querySelector('p'); + const input = document.querySelector('input'); + const btn = document.querySelector('button'); + + btn.addEventListener('click', function() { + let searchName = input.value; + input.value = ''; + input.focus(); + for (let i = 0; i < contacts.length; i++) { + let splitContact = contacts[i].split(':'); + if (splitContact[0] === searchName) { + para.textContent = splitContact[0] + ' の電話番号は ' + splitContact[1] + ' です。'; + break; + } else { + para.textContent = '連絡先が見つかりません。'; + } + } + }); + </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> という変数に格納してから、次の検索に備え、入力欄をクリアし、フォーカスを設定しています。検索に大文字小文字を気にしないよう、文字列に <code><a href="https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">toLowerCase()</a></code> を実行しているのに注意してください。</li> + <li>ここからが本題の for ループです。 + <ol> + <li>カウンター変数を <code>0</code> から始め、<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> にまた <code><a href="https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase">toLowerCase()</a></code> を使って小文字化したものと等しいかを判定します。もし等しければ、連絡先の電話番号を段落 ({{htmlelement("p")}} 要素) に表示し、<code>break</code> を使用してループを終了しています。</li> + </ol> + </li> + <li> <code>(contacts.length-1)</code> 回目の繰り返しの後に、もし連絡先の名前が入力された検索語に一致しなければ、段落に「連絡先が見つかりません。」という文字列を表示し、条件が true では無くなるまでループを継続します。</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="Skipping_iterations_with_continue" name="Skipping_iterations_with_continue">continue で繰り返しをスキップする</h2> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Statements/continue">continue</a> 文は <code>break</code> と同じような動作をします。けれど、ループを完全に抜けてしまうのではなく、次の繰り返しまで飛ばします。それでは、今度は入力として数値を受け取り、その数以下で整数の平方である値のみを返すという例を見てみましょう。</p> + +<p>HTML は基本的に先ほどの例と同様で、1 つのテキストボックスと出力用の段落があります。JavaScript もループ自体を除けばほぼ同じですので、違う部分のみを示します。</p> + +<pre class="brush: js notranslate">let num = input.value; + +for (let i = 1; i <= num; i++) { + let sqRoot = Math.sqrt(i); + if (Math.floor(sqRoot) !== sqRoot) { + continue; + } + + para.textContent += i + ' '; +}</pre> + +<p>出力結果はこちらです。</p> + +<div class="hidden"> +<h6 id="Hidden_code_4" name="Hidden_code_4">Hidden code 4</h6> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>整数の平方根の生成</title> + <style> + + </style> + </head> + <body> + + <label for="number">数値を入力してください: </label> + <input id="number" type="text"> + <button>整数の平方根を生成</button> + + <p>出力結果: </p> + + + <script> + const para = document.querySelector('p'); + const input = document.querySelector('input'); + const btn = document.querySelector('button'); + + btn.addEventListener('click', function() { + para.textContent = 'Output: '; + let num = input.value; + input.value = ''; + input.focus(); + for (let i = 1; i <= num; i++) { + let 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>) です。<code>for</code> ループには、カウンターの初期値として、(今回は 0 ではなく) 1 が与えられ、終了する条件としてカウンターが入力値 (<code>num</code>) より大きくなった場合と指定されており、イテレーターとして、カウンターに 1 ずつ加算するよう指定されています。</li> + <li>ループ内部では、各値の平方根を <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt">Math.sqrt(i)</a> を使用して求め、求めた平方根を切り捨てた値が、切り捨てる前の平方根と等しいかどうかを調べています (切り捨てには <a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a> に任意の数値を渡します)。</li> + <li>もし、平方根と切り捨てた数値が等しくないのなら (<code>!==</code>)、平方根は整数ではないことを示しています。整数以外には興味がありませんので、<code>continue</code> 文を用いて、その数値をどこにも保持することなく、次のループの繰り返しまでスキップします。</li> + <li>もし、その平方根が整数値であるならば、if ブロックは飛ばされるので、<code>continue</code> 文は実行されません。代わりに、現在の <code>i</code> の値を段落の内容の後ろにスペースと一緒に結合します。</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_and_do_..._while" name="while_and_do_..._while">while と do ... while</h2> + +<p><code>for</code> は JavaScript で利用可能な唯一のループのタイプではありません。実際には多くのものがありますが、これらのすべてを理解する必要はありませんが、仕事の同じ機能をわずかに異なる方法で認識できるように、他のものの構造を見ておく価値があります。<br> + <br> + まず、while ループを見てみましょう。このループの構文は次のようになります。</p> + +<pre class="notranslate">初期化処理 +while (条件) { + // 実行するコード + + 最後の式 +}</pre> + +<p>これは for ループとよく似ていますが、初期化条件はループの前に設定され、最後の式は実行するコードの後のループ内に含まれます。これら二つの項目は丸括弧の中に含まれません。条件は、<code>for</code> ではなく <code>while</code> キーワードが前に付いた括弧内に含まれています。<br> + <br> + for ループにもある3つの項目が、for ループとおなじ順序で定義されています。これは理にかなっています。条件が true では無くなるポイントに達したかどうかを確認する前に初期化処理を定義する必要があります ; ループ内のコードが実行された後(1回の繰り返しの完了)、最期の式が実行されます。これは、条件がまだ true である場合にのみ発生します。<br> + <br> + 猫のリストの例をもう一度見てみましょう。ただし、while ループを使うように書き直してみましょう:</p> + +<pre class="brush: js notranslate">let 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>注</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> + +<p><a href="/ja/docs/Web/JavaScript/Reference/Statements/do...while">do ... while</a> ループは非常によく似ていますが、while構造にはバリエーションがあります。</p> + +<pre class="notranslate">初期化処理 +do { + // 実行するコード + + 最後の式 +} while (条件)</pre> + +<p>この場合、初期化処理は、ループが始まる前に、再び最初に来ています。キーワードは、実行するコードと最期の式を含む中括弧の直前にあります。</p> + +<p>ここでの違いは、条件がほかの全ての後にあり、括弧で囲まれ、その前に <code>while</code> キーワードが付いていることです。<code>do...while</code> ループでは、中括弧内のコードは、チェックが再度実行されるかどうかを確認する前に常に 1 回実行されます (while と for の場合、チェックが最初に来るため、コードは実行されない可能性があります) 。<br> + <br> + <code>do...while</code> ループを使用するように、猫のリストの例をもう一度書き直してみましょう:</p> + +<pre class="brush: js notranslate">let 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>注</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>重要</strong>: while と do ... while では、すべてのループと同様に、カウンター変数を増加、もしくは場合により減少させて、最終的に条件が false となるようにする必要があります。そうしなければループは永遠に進み、ブラウザーはそれ強制的に停止させるか、クラッシュします。これは<strong>無限ループ</strong>と呼ばれます。</p> +</div> + +<h2 id="Active_learning_Launch_countdown!" name="Active_learning_Launch_countdown!">アクティブラーニング: カウントダウンを開始します!</h2> + +<p>この練習では、出力ボックスへの簡単な起動カウントダウンを 10 から Blast off まで印字してください。具体的には、</p> + +<ul> + <li>10 から 0 までのループ。イニシャライザを提供します — <code>let i = 10;</code>.</li> + <li>各繰り返しに対して、新しい段落を作成し、それを出力<div>に追加します。これは、<code>const output = document.querySelector('.output');</code>を使用して選択したものです。コメントでは、ループ内のどこかで使用する必要がある 3 つのコード行を提供しました + <ul> + <li><code>const 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 =</code> 行が必要です)。 + <ul> + <li>数字が 10 の場合、パラグラフに "Countdown 10" と出力する。</li> + <li>数字が 0 の場合、パラグラフに "Blast off!" と出力する。</li> + <li>その他の数字では、パラグラフにその数字を出力する。</li> + </ul> + </li> + <li>イテレーターを含めることを忘れないでください!ですが、この例では各反復の後にカウント(アップではなく)ダウンするため、<code>i++</code> は要らないでしょう — 減少方向にどうやって反復しますか?</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: あなたがループ(例えば (while(i>=0))からタイピングを始めると、ブラウザが固まってしまうかもしれません。終了条件をまだ入力していないからです。注意して下さい。この問題に対処するにはコメントの中にコードを書き始めて、完了してからコメントを削除することです。</p> +</div> + +<p>間違えた場合は、「リセット」ボタンを使用してこの例をいつでもリセットできます。あなたが本当に立ち往生したら、"ソリューションを表示"を押して解決策を見てください。</p> + +<div class="hidden"> +<h6 id="Active_learning" name="Active_learning">Active learning</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="height: 410px;overflow: auto;"> + +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> +<textarea id="code" class="playable-code" style="height: 300px;width: 95%"> +let output = document.querySelector('.output'); +output.innerHTML = ''; + +// let i = 10; + +// const 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: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">const textarea = document.getElementById('code'); +const reset = document.getElementById('reset'); +const solution = document.getElementById('solution'); +let code = textarea.value; +let userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +let jsSolution = 'const output = document.querySelector(\'.output\');\noutput.innerHTML = \'\';\n\nlet i = 10;\n\nwhile(i >= 0) {\n let 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}'; +let solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + const scrollPos = textarea.scrollTop; + const caretPos = textarea.selectionStart; + const front = (textarea.value).substring(0, caretPos); + const back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Active_learning_Filling_in_a_guest_list" name="Active_learning_Filling_in_a_guest_list">アクティブラーニング: ゲストリストに記入する</h2> + +<p>この演習では、配列に格納された名前のリストを取得して、それらをゲストリストに入れることが必要です。しかし、これはそれほど簡単ではありません — 彼らは貪欲で失礼で、常にすべての食べ物を食べるので、私たちはフィルとローラを入れさせたくありません! 私たちは 2 つのリストを持っています。1 つは承認するゲストのためのもの、もう 1 つは拒否するゲストのためのものです。<br> + <br> + 具体的には、</p> + +<ul> + <li>0 から <code>people</code> 配列の長さまで反復するループを作成します。<code>let i = 0;</code> の初期化処理で始める必要がありますが、どのような条件が必要ですか?</li> + <li>各ループ反復中に、条件文を使用して現在の配列項目が "Phil" または "Lola" に等しいかチェックします。 + <ul> + <li>そうである場合は、<code>refused</code> パラグラフの <code>textContent</code> の最後に配列項目を連結し、その後にカンマとスペースを続けます</li> + <li>そうでない場合は、配列項目を、<code>admitted</code> パラグラフの <code>textContent</code> の末尾に連結し、その後にカンマとスペースを続けます</li> + </ul> + </li> +</ul> + +<p>私たちはすでにあなたに次のものを提供しました:</p> + +<ul> + <li><code>let i = 0;</code> — イニシャライザー</li> + <li><code>refused.textContent +=</code> — <code>refused.textContent</code> の後に文字を連結する開始行</li> + <li><code>admitted.textContent +=</code> — <code>admitted.textContent</code> の後に文字を連結する開始行</li> +</ul> + +<p>特別ボーナス問題 — 上のタスクを正常に完了すると、カンマで区切られた 2 つの名前リストが残されますが、それらは整頓されません。それぞれの末尾にカンマがあります。それぞれの場合に最後のカンマを切り取り、末尾にピリオドを追加した行をどのように書くかという問題を解決出来ますか?ヘルプのため<a href="https://wiki.developer.mozilla.org/ja/docs/Learn/JavaScript/First_steps/Useful_string_methods">便利な文字列メソッド</a>の記事を見てみてください。<br> + <br> + 間違えた場合は、「リセット」ボタンを使用してこの例をいつでもリセットできます。あなたが本当に立ち往生したら、"ソリューションを表示"を押して解決策を見てください。</p> + +<div class="hidden"> +<h6 id="Active_learning_2" name="Active_learning_2">Active learning 2</h6> + +<pre class="brush: html notranslate"><h2>Live output</h2> +<div class="output" style="height: 100px;overflow: auto;"> + <p class="admitted">Admit: </p> + <p class="refused">Refuse: </p> +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> +<textarea id="code" class="playable-code" style="height: 400px;width: 95%"> +const people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce']; + +const admitted = document.querySelector('.admitted'); +const refused = document.querySelector('.refused'); +admitted.textContent = 'Admit: '; +refused.textContent = 'Refuse: ' + +// let 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: css notranslate">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js notranslate">const textarea = document.getElementById('code'); +const reset = document.getElementById('reset'); +const solution = document.getElementById('solution'); +let code = textarea.value; +let userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +const jsSolution = 'const people = [\'Chris\', \'Anne\', \'Colin\', \'Terri\', \'Phil\', \'Lola\', \'Sam\', \'Kay\', \'Bruce\'];\n\nconst admitted = document.querySelector(\'.admitted\');\nconst refused = document.querySelector(\'.refused\');\n\nadmitted.textContent = \'Admit: \';\nrefused.textContent = \'Refuse: \'\nlet 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) + \'.\';'; +let solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + const scrollPos = textarea.scrollTop; + const tcaretPos = textarea.selectionStart; + const front = (textarea.value).substring(0, caretPos); + const back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Which_loop_type_should_you_use" name="Which_loop_type_should_you_use">どのタイプのループを使用しますか?</h2> + +<p>基本的な用途では for、while、do ... while ループはほぼ互換性があります。それらはすべて同じ問題を解決するために使用することができます。どちらを使用するかは、あなたの個人的な好みに大きく左右されます。これは、どれが最も覚えやすいか、最も直感的かということです。それらをもう一度見てみましょう。</p> + +<p>まずは <code>for</code>:</p> + +<pre class="notranslate">for (初期化処理; 条件; 最後の式) { + // 実行するコード +}</pre> + +<p><code>while</code>:</p> + +<pre class="notranslate">初期化処理 +while (条件) { + // 実行するコード + + 最後の式 +}</pre> + +<p>そして最後は <code>do...while</code>:</p> + +<pre class="notranslate">初期化処理 +do { + // 実行するコード + + 最後の式 +} while (条件)</pre> + +<p>少なくとも最初は <code>for</code> から始めることをお勧めします。すべてを覚えておくことが簡単だからです。初期化処理、条件、最後の式をすべて括弧内にきちんと入れなければならないので、それらがどこにあるかや見落としていないことの確認が簡単です。</p> + +<div class="note"> +<p><strong>注</strong>: 高度な/特殊な状況やこの記事の範囲を超えて有用な、他のループタイプ/機能もあります。ループ学習をさらに進めたい場合は、高度な<a href="https://wiki.developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Loops_and_iteration">ループと反復処理ガイド</a>をお読みください。</p> +</div> + +<h2 id="スキルをテストしよう!">スキルをテストしよう!</h2> + +<p>この記事の最後に到達しましたが、最も大事な情報を覚えていますか?移動する前に、情報を維持しているか検証するテストを見ることができます — <a href="https://wiki.developer.mozilla.org/ja/docs/Learn/JavaScript/Building_blocks/Test_your_skills:_Loops">Test your skills: Loops</a> を見てください。</p> + +<h2 id="Conclusion" name="Conclusion">まとめ</h2> + +<p>この記事では、背後にある基本的な概念と、JavaScript でコードをループする際に使用できるさまざまなオプションについて説明しました。今はループが反復コードを処理するための良い仕組みである理由がはっきり分かり、自身の例で使用できることを誇らしく思うでしょう。<br> + <br> + あなたが理解できなかったことがあれば、記事をもう一度読んだり、ヘルプを求めて<a href="/ja/docs/Learn#Contact_us">私たちに連絡</a>してください。</p> + +<h2 id="See_also" name="See_also">関連情報</h2> + +<ul> + <li><a href="/ja/docs/Web/JavaScript/Guide/Loops_and_iteration">ループと反復処理</a></li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Statements/for">for文のリファレンス</a></li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Statements/while">while</a> と <a href="/ja/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> リファレンス</li> + <li><a href="/ja/docs/Web/JavaScript/Reference/Statements/break">break</a> と <a href="/ja/docs/Web/JavaScript/Reference/Statements/continue">continue</a> リファレンス</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> — 高度なループのベストプラクティス</p> + </li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module" name="In_this_module">このモジュール</h2> + +<ul> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/conditionals">コードでの意思決定 — 条件文</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/Looping_code">ループコード</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/Functions">関数 — 再利用可能なコードブロック</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">独自の関数を作る</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/Return_values">関数の戻り値</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/Events">イベントの紹介</a></li> + <li><a href="/ja/docs/Learn/JavaScript/Building_blocks/Image_gallery">イメージギャラリー</a></li> +</ul> |