1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptのループ設計:for / forEach / map / reduce / for...of すべての使いどころを言語化する

Posted at

概要

ループは、プログラミングにおける最も基本的な制御構文だ。
しかしJavaScriptでは、ループの手段が多すぎる。

  • for
  • forEach
  • map
  • reduce
  • for...of
  • for...in

「なんとなく使ってる」では、バグ・非効率・可読性の劣化を招く。
この記事では、それぞれのループ構文の構文的な違いと使い分けの判断軸を、設計目線で整理していく。


対象環境

ES6以降のJavaScript(Node.js / ブラウザ)

各ループ構文の特徴と選定基準

構文 主な用途 副作用あり return値 中断可 イテラブル対応 適しているケース
for 汎用 ❌ undefined break 制御フローが複雑 / 索引アクセスが必要
forEach 配列の処理 ❌ undefined ❌不可 単純な副作用処理
map 配列を変換して返す ❌推奨外 ✅ 配列 ❌不可 配列変換ロジック
reduce 配列を単一値に畳み込む ❌推奨外 ✅ 任意値 ❌不可 集計・合計・構造変換
for...of 任意のイテラブル処理 ❌ undefined break 配列 / Set / Map の繰り返し処理
for...in オブジェクト列挙 ❌ undefined break キー列挙のみ。配列には不向き

それぞれの実例と解説

1. for

for (let i = 0; i < items.length; i++) {
  console.log(items[i]);
}
  • ✅ 高い柔軟性
  • ❌ 長くなりがち
  • ✅ 中断可能 (break, continue)

2. forEach

items.forEach(item => {
  console.log(item);
});
  • ✅ 簡潔
  • return, break できない
  • ❌ チェーン不可(return値なし)

3. map

const doubled = items.map(x => x * 2);
  • ✅ 「変換」に強い(1対1の変換)
  • ❌ 副作用は禁止
  • ✅ チェーン可能

4. reduce

const total = items.reduce((acc, cur) => acc + cur, 0);
  • ✅ 単一値の集約に最適
  • ✅ 初期値を使って安全に設計可能
  • ❌ 初見では読みにくいことも

5. for...of

for (const item of items) {
  console.log(item);
}
  • ✅ シンプルで安全
  • ✅ break / continue / return 可能
  • ✅ 配列 / Set / Map / arguments に対応

6. for...in

for (const key in obj) {
  console.log(`${key}: ${obj[key]}`);
}
  • ✅ オブジェクトのキー列挙に適している
  • ❌ 配列に使うとインデックス順が保証されない
  • ❌ プロトタイプ継承の影響を受ける

→ ✅ Object.hasOwn() との併用が安全:

for (const key in obj) {
  if (Object.hasOwn(obj, key)) {
    // ...
  }
}

ループ選定の設計思考

目的 推奨構文
配列を変換したい map
累積して1つの値を導出したい reduce
副作用処理(API呼び出しなど) forEach
breakしたい for, for...of
イテラブル全般を処理したい for...of
オブジェクトのキーを走査 for...in(+ hasOwn)

よくある誤用

map を副作用目的で使う

items.map(item => console.log(item)); // ❌ 非推奨

→ ✅ forEach もしくは for...of を使うべき


for...in を配列に使う

for (const i in arr) {
  console.log(arr[i]); // ❌ インデックス順を保証しない
}

→ ✅ for, for...of が適切


forEach で早期リターンしようとする

items.forEach(item => {
  if (item > 10) return; // ❌ これは次のループをスキップしない
});

→ ✅ for / for...of に置き換える


結語

ループ処理とは、単なる反復ではない。
意図を明示するための制御構造であり、責任の分岐点でもある。

すべてのループ構文には、それが設計された理由がある。
その意図を汲み取り、機能だけでなく意味を持った選定を行うこと。

コードの動作を決めるのは構文だが、
コードの価値を決めるのは設計である。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?