この記事では、繰り返し処理とは何かについて詳しく解説します。
解説:
JavaScript では、配列を処理するための便利なメソッドがいくつも用意されています。
代表的なものが「map」「filter」「reduce」などの高階関数たち。
これらをマスターすると、for文を書かずにスマートなコードが書けるようになります。
この章では、それぞれの意味・使いどころ・違いを、具体例とともに解説します。
// 例:価格の配列を税込価格に変換する
const prices = [100, 200, 300];
const withTax = prices.map(p => p * 1.1);
console.log(withTax);
// 結果 : [110, 220, 330]「元の配列と同じ数だけ要素を持つ、新しい配列を作りたい」ときに使います。
// 例:300円以上の商品だけ取り出す
const prices = [100, 200, 300, 400];
const expensive = prices.filter(p => p >= 300);
console.log(expensive);
// 結果 : [300, 400]「必要なものだけ残す」処理にぴったりです。
// 例:合計金額を求める
const prices = [100, 200, 300];
const total = prices.reduce((acc, p) => acc + p, 0);
console.log(total);
// 結果 : 600
「ひとつの値にまとめたい」ときに使います。
1つ目の引数「acc」はこれまでの合計、2つ目の「p」は現在の要素を表します。
// 例:100円未満の商品があるか?
const prices = [120, 80, 300];
const hasCheap = prices.some(p => p < 100);
console.log(hasCheap);
// 結果 : true「1つでもあれば true」というチェックに使えます。
// 例:すべての商品が100円以上か?
const prices = [120, 180, 300];
const allExpensive = prices.every(p => p >= 100);
console.log(allExpensive);
// 結果 : true「全部そうなら true」 という条件チェックに便利です。
// 例:100円未満の最初の商品を探す
const prices = [120, 80, 300];
const firstCheap = prices.find(p => p < 100);
console.log(firstCheap);
// 結果 : 80見つかった最初の要素を返し、条件に合う要素がなければ undefined を返します。
| メソッド | 用途 | 返り値 |
|---|---|---|
| map | 変換 | 要素数そのままの配列 |
| filter | 絞り込み | 条件を満たす配列 |
| reduce | 集計 | 単一の値 |
| some | 1つでも条件に合えば true | true / false |
| every | すべて条件に合えば true | true / false |
| find | 最初の1件 | 要素 or undefined |
これらを使いこなせると、「読みやすい」「バグりにくい」コードにぐっと近づきます。
次は、これらの書き方を「どう選ぶか?」という判断のコツを紹介していきます!
解説:
JavaScript では「for」「for...of」「forEach」「map」など、同じことを別の書き方で実現できる場面が多くあります。
でも、だからこそ「どれを選ぶべきか」に迷いやすいのも事実です。
この章では、それぞれの文法がどんな目的に向いているか、どう選べばいいかを整理してお伝えします。
柔軟で何でもできる一方、ややコード量が増えます。
ループのインデックスやカウンタが必要なときに最適。
// 例:3つおきに表示したいなど、細かい制御が必要なとき
const array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for (let i = 0; i < array.length; i += 3) {
console.log(array[i]); // 結果 : 0, 3, 6, 9
}インデックスが必要な処理にはやっぱり「for」が頼りになります。
配列の中身を順に処理するのに便利です。
配列の各要素を使って、何かの処理を実行したいときに使います。
たとえば「画面に表示する」「ログを出す」「関数を呼ぶ」など、結果を返すのではなく、見える動作を起こす処理に向いています。
// 例:画面に項目を表示する
items.forEach(item => {
renderItem(item); // HTMLに描画
});配列を変換する目的ではなく、「処理を実行する」目的なら forEach がシンプル。
変換して新しい配列を作るなら map 一択。
逆に、変換結果を使わないのに map を使うのは NG。
// ❌ これは map を使うべきではない例
items.map(item => {
console.log(item);
});
// 結果は配列に使われていない → forEach が正解
// ✅ 正しい map の使い方
const doubled = items.map(item => item * 2);
console.log(doubled);「その処理が map を使うべき理由があるか?」を考えることが大事です。
| 文法 | 向いているケース | 補足 |
|---|---|---|
| for | インデックスが必要/制御が複雑 | 万能だが冗長になりやすい |
| forEach | 値を使って何かを「実行」する処理 | 戻り値が必要ないならこれでOK |
| map | 変換して配列として使いたい | 使わない map は NG |
「目的」と「結果をどう使うか?」を軸に考えれば、書き方で迷う時間がぐっと減ります。
次は、実際に「同じ処理を複数の書き方で比べてみる」ことで、違いを実感していきましょう!
解説:
これまでの章で、それぞれの書き方の特徴を学んできました。
今回は「同じ目的の処理」を for / forEach / map の3通りで書き比べて、実際にどんな違いがあるかを見てみましょう。
今回のお題は、「名前の配列をもとに、1人ずつ敬称『さん』をつけて表示または返す」処理です。
const names = ['田中', '佐藤', '鈴木'];
const result = [];
for (let i = 0; i < names.length; i++) {
const withSuffix = names[i] + 'さん';
result.push(withSuffix);
}
console.log(result);
// 結果 : ['田中さん', '佐藤さん', '鈴木さん']わかりやすく柔軟ですが、処理が少し長めになりがちです。
const names = ['田中', '佐藤', '鈴木'];
const result = [];
names.forEach(name => {
result.push(name + 'さん');
});
console.log(result);
// 結果 : ['田中さん', '佐藤さん', '鈴木さん']書き方はすっきり。返り値はないので、「実行が目的」という意図が明確です。
const names = ['田中', '佐藤', '鈴木'];
const result = names.map(name => name + 'さん');
console.log(result);
// 結果 : ['田中さん', '佐藤さん', '鈴木さん']処理内容と意図(配列変換)が1行で表現されており、読みやすさ・意図の明確さともに優れています。 同じような処理でも、mapを使えば「何のための処理か」がひと目でわかるのが魅力です。
| 書き方 | 特徴 | 向いている場面 (どう使い分ける?) |
|---|---|---|
| for | 自由度が高く、細かい制御が可能 | 条件付き、途中 break、インデックス使用など |
| forEach | 順に処理を実行するだけならシンプル | 表示処理や副作用を目的とする場合 ※副作用:console.log や DOM操作など、値を返すのではなく「外部に影響を与える処理」 |
| map | 要素を変換して新しい配列を返す | 変換結果を配列として使いたい場合 |
処理の「見た目」だけでなく、「目的(何のための処理か)」によって選ぶべき構文が変わることを体感できたでしょうか?
書き方に迷ったら、「**結果を使うのか、処理するだけか**」を考えるのがポイントです。
次は「**for...in を配列に使うとどうなるのか?**」という、よくある落とし穴を解説します!
解説: JavaScript には、オブジェクトのループに使う for...in と、配列のループに使う for...of や forEach などがあります。 しかし初心者の方がやりがちなのが、「for...in を配列に使ってしまう」というミスです。
結論から言うと、配列には for...in は基本的に使わない方が安全です。
その理由を順に見ていきましょう。
for...in は、オブジェクトの「プロパティ名(キー)」を1つずつ取り出す構文です。
// オブジェクトに使うのが正しい使い方
const user = { name: "太郎", age: 25 };
for (const key in user) {
console.log(key); // 結果 : name, age
console.log(user[key]); // 結果 : 太郎, 25
}配列にも「キー(インデックス番号)」があるので、一見 for...in が動くように見えます。
// 一見ちゃんと動くように見える
const fruits = ["りんご", "みかん", "バナナ"];
for (const i in fruits) {
console.log(i, fruits[i]); // 結果 : 0 りんご, 1 みかん, 2 バナナ
}ですが、この使い方には落とし穴があります。
// 配列に余計なプロパティをつけると...
const fruits = ["りんご", "みかん", "バナナ"];
fruits.custom = "オマケ";
for (const i in fruits) {
console.log(i, fruits[i]);
}
// 結果 : 0 りんご, 1 みかん, 2 バナナ, custom オマケ ← これが問題このように、意図しないプロパティまで処理してしまう可能性があるため、配列には使うべきではないとされています。
「for...in はオブジェクト用、配列には使わない」
迷ったら for...of を基本に考えよう。
次は「配列処理のスピードが気になる人向けに、実行速度の傾向」について紹介します。
解説:
「結局、一番速いのはどれなの?」と気になる方も多いかもしれません。
ここでは for / forEach / map / for...of など、よく使う繰り返し構文の実行速度の傾向についてざっくり整理しておきます。
ただし!以下の点にご注意ください:
| 構文 | 速度(目安) | コメント |
|---|---|---|
| for | ◎(最速クラス) | 無駄が少なく、JSエンジンが最適化しやすい |
| for...of | ◯ | やや遅くなるが、コードがすっきり |
| forEach | △ | 関数コールのオーバーヘッドあり(やや重) |
| map / filter / reduce | △〜◯ | 関数型なので見た目はきれいだが、速度は控えめ |
実務では、1秒間に100万回回すような処理でなければ、速度差は誤差の範囲です。
それよりも大事なのは、意図が伝わる書き方をすることです。
たとえば、「変換したい」なら map、「処理を実行したい」なら forEach、インデックスが必要なら for ——
こうした目的と構文の対応関係が明確であるほうが、あとから読む人にとって理解しやすくなります。
ブラウザの開発者ツールなどで console.time を使えば、処理速度を計測することも可能です。
const array = Array(100000).fill(1);
// for
console.time('for');
for (let i = 0; i < array.length; i++) {
const x = array[i] * 2;
}
console.timeEnd('for');
// forEach
console.time('forEach');
array.forEach(val => {
const x = val * 2;
});
console.timeEnd('forEach');※ 実行時の数値は端末やブラウザにより異なります。
速度を求める場面ではこうした手法でベンチマークを取りつつ、基本は読みやすさ重視で選びましょう!
これで「配列操作と選び方のコツ」パートは終了です。次は「現場でも活きるループ応用編」に進んでいきましょう!