JavaScriptのforループと、使うべきループの選び方
JavaScriptのループ比較
JavaScriptのforループとその他すべてのループをその場で比較 | We.Inc
for、for...of、for...in、while、do...while、forEachを並べて比較。配列、文字列、オブジェクト、Mapで各ループを実行し、出力や発生するエラーを確認できます。
基本のforループは3つの部分からなります:for (let i = 0; i < arr.length; i++) { ... }。インデックスや独自の増分が必要なときに使います。値だけが必要ならfor...of、オブジェクトのキーにはfor...inかObject.entriesを使い、何回繰り返すか事前にわからないときはwhileを使います。
用途に合ったループ
- for (let i = 0; i < n; i++)
- 数を数える、インデックスで参照する、逆順や2つ飛ばしで進む
- できる
- for (const x of iterable)
- 配列、文字列、Map、Set、NodeListなどの値
- できる
- for (const key in obj)
- プレーンオブジェクトのキー(継承したものを含む)
- できる
- while (condition)
- 何かが変わるまで繰り返す、回数が不明
- できる
- do { } while (condition)
- 同上、ただし必ず1回は実行される
- できる
- arr.forEach(fn)
- 配列の全要素に対する副作用
- できない(例外を投げる場合のみ)
このページのループはどれもコードを繰り返しますが、各回で何を渡すか、何を対象にできるか、どう抜けるかが異なります。下のランナーでは、各ループを4種類のデータに対して実行し、実際の出力を確認できます。配列にfor...inを使う、プレーンオブジェクトにfor...ofを使うといった間違いにすぐ気付けます。
- ループとデータの種類を選びます。ページがそのループをブラウザー内で実際に実行します。
- 出力パネルには、各回でループ変数が持っていた値、またはその組み合わせで発生したエラーが表示されます。
- 途中終了のオプションをオンにすると3回目で止まり、どのループが対応しているかがわかります。
- 下の例から好きなパターンをコピーしましょう。
- カウンターはvarではなくletで宣言しましょう。letなら各回が独自のコピーを持つので、ループ内で作ったコールバックが正しい数値を参照します。
- 変数を再代入しない場合、for...ofとfor...inではconstを使いましょう。各回で新しい束縛が作られます。
- forEachは非同期のコールバックを待ちません。各要素を順番にawaitするには、非同期関数の中でfor...ofとawaitを使いましょう。
- whileループの条件が必ずfalseになりうるようにしましょう。条件で使う変数を本体の中で変更しないと、タブが固まってしまいます。
よくある質問
for...ofとfor...inの違いは何ですか?
for...ofは、配列の要素や文字列の文字など、反復可能なものから値を取り出します。for...inは、継承した列挙可能なものも含めて、プロパティ名を文字列で返します。配列にfor...inを使うと、要素ではなく'0'、'1'、'2'が返ります。
forEachループを途中で抜けるには?
例外を投げる以外に方法はありません。途中終了に対応したfor...ofか、答えが見つかった時点で自動的に止まるsome、every、find、findIndexに切り替えましょう。
JavaScriptでオブジェクトをループするには?
for (const [key, value] of Object.entries(obj))を使います。オブジェクト自身のキーだけが対象になり、キーと値の両方が得られます。プレーンオブジェクトにfor...ofを直接使うと、TypeError: obj is not iterableが発生します。
入れ子の2つのループを一度に抜けるには?
外側のループの前にラベルを付け、breakで指定します:outer: for (...) { for (...) { if (found) break outer; } }。continue outerを使うと、代わりに外側のループの次の回へ進みます。
逆順にループするには?
最後のインデックスから始めてカウントダウンします:for (let i = arr.length - 1; i >= 0; i--)。まだ訪れていない位置がずれないので、ループ中にspliceで要素を削除する安全な方法でもあります。
forループの3つの部分を読み解く
- 1つ目の部分は最初に1回だけ実行され、通常はカウンターを作ります。2つ目は毎回の前にチェックされ、falseになった時点でループが終わります。3つ目は各回の後に実行され、通常はカウンターを進めます。
- どの部分も空にできます。for (;;)はbreakかreturnでしか終わらないループで、内部に明確な脱出条件を持つ再試行の処理などでたまに役立ちます。
break、continue、ラベル
- breakは最も内側のループをすぐに抜けます。continueは現在の回の残りを飛ばして次の回へ進みます。どちらもfor、for...of、for...in、while、do...whileで使えますが、forEachのコールバックでは使えず、そこでのreturnはその1回の呼び出しを終えるだけです。
- ラベルは、文の前に置く名前とコロンです。break labelとcontinue labelでその外側の文を対象にできるので、入れ子のループをまたいで見つかったかどうかのフラグを管理する必要がなくなります。
コピーできるループのパターン
基本のfor:順方向、逆方向、一定間隔
開始値、条件、増分を変えれば、好きな方法で数えられます。
インデックス付きのfor...of
entries()が各値とその位置をペアにするので、カウンターなしで両方が得られます。
whileとdo...while
do...whileは本体の後に条件をチェックするので、条件が最初からfalseでも本体が1回実行されます。
ラベルで入れ子のループを抜ける
break gridは、最初に一致するものが見つかった時点で両方のループを止めます。
各要素を順番にawaitする
for...ofは各awaitで一時停止します。同じコードをforEachの中に書くと、すべてのリクエストを一度に開始し、待ちません。
ループランナー
ループとデータを選んでください。ループが実際に実行され、各回が下に一覧表示されます。
ループ
データ
配列
文字列
プレーンオブジェクト
Map
3回目の後に途中終了する
実行されるコード
出力
{n}回目:{v}
forEachにはbreakがありません。コールバック内のreturnはその1回の呼び出しを終えるだけなので、すべての回が実行されます。
{v}が発生します
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る