はじめに
こんにちは!堕罪オサムです。
私、for文とかのループ処理を書くのがめっちゃ苦手なんです……。だからなんだよと言われるとアレなんですけども。泣
あまりにfor文が分からなかったので、for文の中身を分解して理解を深めようと思います!
また後半はfor文以外のループ処理についても引用をして理解を深めました。
for文やループ処理が苦手だといった仲間がいらっしゃいましたらぜひ読んでみてほしいです。
よろしくお願いします!
for文とは
for文(for statement)とは、多くのプログラミング言語に用意されている構文の一つで、繰り返し(ループ)処理を記述するためのもの。決まった回数の繰り返しを記述するために用いられることが多い。
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を使うことが多いです。
for文以外のループ処理
JavaScriptでのループ処理は以下のような種類があります。
- while文
- do...while文
- for...in 文
- for...of 文
- ラベルつき文
- break 文
- continue 文
- forEach() <=別節で紹介
break文・continue文は以前投稿した「breakとreturnとcontinueの違いがよく分からんのでまとめてみたよ~!」でまとめたので今回は割愛させていただきます。
説明文は↑リンクから引用します。
while文
while文
は指定された条件がtrue
に評価される限り文を実行します。
条件式がfalse
となる場合、ループ内の文は実行を停止し、ループに続く文に制御が渡されます。
ループ内の文が実行される前に条件がテストされます。
条件がtrue
を返す場合、文は実行され、条件が再びテストされます。
条件がfalse
を返す場合、実行は停止し、while
の次の文に制御が渡されます。
複数の文を実行するには、それらの文をグループ化するブロック文({ ... })
を使用します。
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
の次の文に渡ります。
//次の例では、do ループは少なくとも一度繰り返されます。
//そして i が 5 未満でなくなる直前まで繰り返されます。
let i = 0;
do {
i += 1; //文
console.log(i); //文
} while (i < 5); //(条件式)
for...in 文
for...in文
はオブジェクトにあるすべての列挙可能なプロパティに対し指定された変数を通して反復処理を行います。
それぞれの異なるプロパティに、JavaScriptは指定された文を実行します。for...in文
は下記のようになります
//次の関数は引数としてオブジェクトと、そのオブジェクトの名前を表す文字列を取ります。
//それからすべてのオブジェクトのプロパティに対して反復し、プロパティ名とその値を表示する文字列を返します。
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 オブジェクトなどを含む)を反復処理するループを生成し、それぞれのプロパティの値に対して実行したい文をともなって作られた反復処理フックを呼び出します。
// 次の例では、`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 ループなどで使用できます。
// イテラブルなオブジェクトの例
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()
はループと反復処理ではなくArray.prototype.forEach()に記載があったため節を分けて記載します。
forEach()メソッド
は反復処理メソッドです。指定された関数callbackFn
を配列に含まれる各要素に対して一度ずつ、昇順で呼び出します。
const array1 = ['a', 'b', 'c'];
array1.forEach((element) => console.log(element));
// Expected output: "a"
// Expected output: "b"
// Expected output: "c"
for ループから forEach への変換
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文についても発見がありました。
ここまでご覧いただきありがとうございました!