初学者ワイ、ループ処理につまづいたので調べてみた。

# はじめに

こんにちは！[堕罪ｵｻﾑ](https://qiita.com/awesomeDazzaye)です。

私、**for文**とかのループ処理を書くのがめっちゃ苦手なんです……。だからなんだよと言われるとアレなんですけども。泣

あまりにfor文が分からなかったので、for文の中身を分解して理解を深めようと思います！

また後半はfor文以外のループ処理についても引用をして理解を深めました。

**for文やループ処理が苦手だ**といった仲間がいらっしゃいましたらぜひ読んでみてほしいです。

よろしくお願いします！

## for文とは


>for文（for statement）とは、多くのプログラミング言語に用意されている構文の一つで、繰り返し（ループ）処理を記述するためのもの。決まった回数の繰り返しを記述するために用いられることが多い。
>
>*引用:[IT用語辞典　for文 【for statement】 forループ / for loop　](https://e-words.jp/w/for%E6%96%87.html)から*

```javascript
for (初期化式; 条件式; 変化式){} // {}内に処理を書く

// よく見る形式はこれ
for (let i = 0; i < 9; i++){
  //以下実行する処理
}
```

## めっちゃくちゃわかるように分解・説明

今回は初期値をx、条件式の値をyとして説明します。

**var i = x;**
初期値が入る・たいていの場合は`0`にする。

**i < y;**
何回ループするかの条件。例えば`i<9`だったら`i`が8になるまで処理が続く。

**i++**
上の例でいうとyが9の場合、9になったとき(`i<9`が正しくなくなったとき)に処理を止めるために`i`を1づつ増やしている。

## なぜ`i`を使うのか
>ループカウンタで変数iがよく使われている理由は、最も古い高級プログラミング言語のFORTRANの暗黙ルールが由来とされています。
>この暗黙ルールでは、型の宣言をしていない変数名の先頭文字が'A'から'H'、'O'から'Z'の場合は実数型、それ以外のIからNは整数型となります。
>ループに使う変数は整数型なので、古いFORTRANではループを作るときは変数名Iを使っていました。
>(中略)
>FORTRANより後に出てきたプログラミング言語のC言語、Javaでも慣習で、ループの変数にi、j、k、l、mを使うことが多いです。
>
>引用:*[Javaを使ったプログラミング学習 ゆるゆるプログラミング](https://talavax.com/variable-i.html#gsc.tab=0)*　から

## for文以外のループ処理

JavaScriptでのループ処理は以下のような種類があります。

- while文
- do...while文
- for...in 文
- for...of 文
- ラベルつき文
- break 文
- continue 文
- **forEach()** <=別節で紹介
 
:::note warn
break文・continue文は以前投稿した[「breakとreturnとcontinueの違いがよく分からんのでまとめてみたよ～！」](https://qiita.com/awesomeDazzaye/items/2e11bfe8b8715df2c54b)でまとめたので今回は割愛させていただきます。
:::

https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Loops_and_iteration

説明文は↑リンクから引用します。

### while文

>`while文`は**指定された条件が`true`に評価される限り文を実行します。**
条件式が`false`となる場合、ループ内の文は実行を停止し、ループに続く文に制御が渡されます。
ループ内の文が実行される前に条件がテストされます。
条件が`true`を返す場合、文は実行され、条件が再びテストされます。
条件が`false`を返す場合、実行は停止し、`while`の次の文に制御が渡されます。
複数の文を実行するには、それらの文をグループ化するブロック文`({ ... })`を使用します。

```javascript
let n = 0;
let x = 0;
while (n < 3) {  // このwhile ループは、n が 3 未満の場合繰り返されます。
  n++;
  x += n;  //各反復で、n がインクリメントされ、その値が x に加算されます。
}
```
【結果】
- 1 回目の反復後 : n = 1, x = 1
- 2 回目の反復後 : n = 2, x = 3
- 3 回目の反復後 : n = 3, x = 6

### do...while文

>`文`は条件式がチェックされる前に毎回一度実行されます。(複数の文を実行するには、ブロック文`({ ... })`を使って一つの文にします)。
>条件式が`true`の場合、文が再び実行されます。
文の実行終了時に毎回条件がチェックされます。
条件が`false`の場合、実行は停止し、制御は`do...while`の次の文に渡ります。

```javascript
//次の例では、do ループは少なくとも一度繰り返されます。
//そして i が 5 未満でなくなる直前まで繰り返されます。
let i = 0;
do {
  i += 1;           //文
  console.log(i);  //文
} while (i < 5);  //(条件式)
```

### for...in 文
>`for...in文`はオブジェクトにあるすべての列挙可能なプロパティに対し指定された変数を通して反復処理を行います。
それぞれの異なるプロパティに、JavaScriptは指定された文を実行します。`for...in文`は下記のようになります

```javascript
//次の関数は引数としてオブジェクトと、そのオブジェクトの名前を表す文字列を取ります。
//それからすべてのオブジェクトのプロパティに対して反復し、プロパティ名とその値を表示する文字列を返します。
function dump_props(obj, obj_name) {
  let result = "";
  for (let i in obj) {  // (変数 in オブジェクト)
    result += obj_name + "." + i + " = " + obj[i] + "<br>";
  }
  result += "<hr>";
  return result;
}
```
>**`Array`の要素に対して反復処理を行う方法として`for...in`文を使用したくなるかもしれませんが、これは数値のインデックスに加えてユーザー定義プロパティの名前も返します。**
そのため、**配列に対しての反復処理には、数値のインデックスを使い従来の`for`ループを使用するほうが良いです。**
なぜなら、(カスタムプロパティやカスタムメソッドを追加するといった) Array オブジェクトの変更を行った場合、`for...in`文は配列要素に加えてユーザー定義プロパティに対しても反復処理するからです。

### for...of 文

>`for...of文`は、反復可能オブジェクト (en-US)（Array、Map、Set、arguments オブジェクトなどを含む）を反復処理するループを生成し、それぞれのプロパティの値に対して実行したい文をともなって作られた反復処理フックを呼び出します。

```javascript
// 次の例では、`for...of`ループと`for...in`ループとの違いを示しています。
// for...in はプロパティ名に対し反復処理される一方、for...of はプロパティの値に対し反復処理します
const arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) { // for...in文の例
//配列「arr」の値が、変数に1つずつ代入されていく。
  console.log(i); // 変数i："0", "1", "2", "foo" が出力される文
}

for (let i of arr) { // for...of文の例　「配列」の値を1つずつ「変数」へ代入する。
  console.log(i); // 変数i：3, 5, 7 が出力される文
}
```
注意しなければならないのは、**for...of文**は、**イテラブル(反復可能である)・オブジェクト**の場合のみ利用できるという点です。

>JavaScriptにおいて、イテラブル（反復可能）なオブジェクトは、Symbol.iteratorと呼ばれる特別なメソッドを持つオブジェクトです。このメソッドは、オブジェクト自体が反復可能であるかどうかを示します。イテラブルなオブジェクトは、for...of ループなどで使用できます。

```javascript
// イテラブルなオブジェクトの例
const iterableObject = {
  values: [1, 2, 3, 4],
  [Symbol.iterator]: function () { // Symbol.iteratorプロパティには、イテレータを生成するための関数が設定されている。
    let index = 0;
    const values = this.values;

    return {
      next: function () { // nextはイテレータが次の値を返すためのメソッド。
        return index < values.length
          ? { value: values[index++], done: false }
          : { done: true };  //三項演算子。
      }
    };
  }
};

// for...of ループでイテラブルなオブジェクトを使用
for (const value of iterableObject) {
  console.log(value);
  // 1
  // 2
  // 3
  // 4
}
```
>[Symbol.iterator] プロパティ:
[Symbol.iterator] は、特殊なシンボルで、オブジェクトがイテラブルであることを示すために使用されます。このプロパティには、イテレータを生成するための関数が設定されています。
>
>`done`プロパティは、イテレーションが終了したかどうかを示すブール値。イテレーションが続く場合は `false`、終了した場合は`true`が設定されます。
`index`が`values`配列の長さよりも小さい場合は`done:false`のオブジェクトを返します。
それ以外の場合は`done: true`のオブジェクトを返します。
>
>この例では、iterableObjectはSymbol.iteratorメソッドを持ち、そのメソッドはイテレータを返します。
イテレータはnextメソッドを持ち、各呼び出しで次の値と反復の終了を示すdoneプロパティを返します。このようなイテラブルなオブジェクトは、自分で定義することもできますが、JavaScriptには既にいくつかの組み込みのイテラブルなオブジェクトもあります。例えば、配列（Array）、文字列（String）、Map、Setなどが挙げられます。これらのオブジェクトは、デフォルトでSymbol.iteratorメソッドを持っており、for...ofループなどで直接反復できます。
>引用：ChatGPT

## forEach()について

公式ドキュメントでは`forEach()`は[ループと反復処理](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Loops_and_iteration)ではなく[Array.prototype.forEach()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)に記載があったため節を分けて記載します。

>`forEach()メソッド`は**反復処理メソッド**です。指定された関数`callbackFn`を配列に含まれる各要素に対して一度ずつ、昇順で呼び出します。

```javascript
const array1 = ['a', 'b', 'c'];

array1.forEach((element) => console.log(element));

// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
```

### for ループから forEach への変換

```javascript
const items = ["item1", "item2", "item3"];
const copyItems = [];

// before
for (let i = 0; i < items.length; i++) {
  copyItems.push(items[i]);
}

// after
items.forEach((item) => {
  copyItems.push(item);
});
```

# 最後に

今回はfor文を分解して理解を深めて、ほかのループ処理についても調査しました。
最後のほうは引用ばかりになってしまいましたが、個人的には**forループからforEach()** への変換や、**while文**についても発見がありました。

ここまでご覧いただきありがとうございました！