for-of で配列を走査する

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

for-of で配列を走査する とは

配列の要素を直接取り出せる for-of 文を学び、配列内の最大値を求める関数を書こう。本レッスンでは、for-of で配列を走査する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

for-of は「配列の中身を順番に取り出す」モダンなループ

配列を扱うとき、要素を 1 つずつ処理したい場面は山ほどあります。これまでに学んだ for 文でもできますが、JavaScript には 配列専用の便利なループ構文 があります。それが今回学ぶ for-of 文です。

for-ofES2015 (ES6) で導入されたモダンな構文で、配列だけでなく文字列・MapSetNodeList など、反復可能 (iterable) なものなら何でも走査できます。インデックスを意識せずに 値そのもの が手に入るのが最大の魅力で、Pythonfor x in list:Java の拡張 for 文 (for (var x : list)) と同じ発想です。

まず、配列の要素を console.log で表示する処理を従来の for 文で書くとこうなります。

JavaScript

const fruits = ['apple', 'banana', 'cherry']; for (let i = 0; i < fruits.length; i++) { const fruit = fruits[i]; // fruit を使う }

for-of を使うと、同じことをこう書けます。

JavaScript

const fruits = ['apple', 'banana', 'cherry']; for (const fruit of fruits) { // fruit を使う }

圧倒的にスッキリしました。i を管理する必要も、fruits[i] で取り出す必要もありません。配列の中身に集中できます。

for-of 文の文法

JavaScriptfor-of 文の基本形は次のとおりです。

JavaScript

for (const 変数 of 反復可能オブジェクト) { // 変数を使った処理 }

大事なポイントは次の通りです。

  • of キーワード を使う (in ではない、これは別の構文)
  • 左辺の変数const で宣言するのが基本 (ループの中で再代入しないなら)
  • 右辺 には配列や文字列など、反復可能なものを書く
  • 中身は 要素そのもの変数 に入る (インデックスではない)

例えば文字列に対しても使えます。

JavaScript

for (const char of 'hello') { // char に 'h', 'e', 'l', 'l', 'o' が順に入る }

for-of は配列だけのものではなく、反復可能ならなんでも 走査できるのがポイントです。

const で宣言するの? ループのたびに値が変わるのに?」という疑問は自然です。実は for-of のループ変数は 毎回新しいスコープで宣言 されるので、各回ごとに別の const として扱われます。なので再代入していないことになり、const で問題ありません。

インデックスも欲しい場合は entries

for-of は値だけを取り出しますが、「インデックスも一緒に欲しい」場面もあります。そんなときは配列の entries() メソッドと 分割代入 を組み合わせます。

JavaScript

const fruits = ['apple', 'banana', 'cherry']; for (const [index, fruit] of fruits.entries()) { // index に 0, 1, 2 が、fruit に値が入る }

entries()[インデックス, 値] のペアを順番に返してくれるイテレータで、それを分割代入で 2 つの変数に取り出しています。「インデックスが必要なら entries()」と覚えておきましょう。

実行フローを図で追ってみる

for (const num of arr) のループの流れは次のとおりです。

diagram (will load when visible)

通常の for のような「初期化・条件・更新」という 3 要素はなく、「次の要素を取って、あれば本体実行、なければ終了」というシンプルな流れになっているのが分かります。

よくある間違い

for-of 文を使い始めるとき、初心者がハマる落とし穴が 3 つあります。

  • ofin を取り違えるfor (const x in arr) と書くと、これは for-in 文で配列の インデックス (文字列) が返ってきます。値が欲しいときは必ず of を使いましょう
  • オブジェクトに対して使えると思い込む — 普通のオブジェクト ({ name: 'Alice', age: 30 }) は iterable ではないので、for (const x of obj) はエラーになります。オブジェクトを走査するときは for-inObject.entries() を使います
  • インデックスが欲しいのに無理に for-of で書こうとする — 自分で let i = 0; を外に出して i++ で管理し始めると、結局 for 文と変わりません。素直に entries() を使うか、従来の for を使いましょう

モダンな JavaScript では、配列の各要素を加工するときは for-of よりも Array.map Array.filter Array.reduce といった高階関数を使うのが主流です。for-of は「副作用 (外部の変数を書き換える) を伴う処理」「途中で break したい処理」のときに重宝します。場面に応じて使い分けましょう。

もうひとつ、for-of の中では break continue も普通に使えます。for-each メソッド (arr.forEach) は break できないので、「途中で抜けたい」場面では for-of のほうが便利です。

やってみよう

それでは今回の課題に取り組みましょう。やることは次の通りです。

  1. findMax(numbers) 関数の中身を埋める
  2. for-of 文を使って配列 numbers の中の 最大値 を求めて返す
  3. findMax([3, 1, 4, 1, 5, 9, 2, 6])9findMax([-3, -1, -10])-1findMax([7])7 になるかを確認する

ヒントとして、最大値を覚えておく変数 max を「配列の最初の要素」で初期化し、for (const num of numbers) で各要素を取り出して num > max なら更新していきます。Math.max(...numbers) のような楽な書き方もありますが、今回はループの練習なので必ず for-of を使ってください

余裕があれば、空配列 [] を渡されたときどうするかも考えてみてください。今回のテストでは空配列は扱いませんが、本番では「想定外の入力で何が起きるか」を考える癖が役立ちます。

この先のレッスンでは、オブジェクトに使える for-in や、ループ制御の break continue、ネストしたループへと進んでいきます。for-of は実務でも頻繁に使う構文なので、しっかり身体に馴染ませましょう。

よくある質問

Q. ブラウザと Node.js で動作は変わりますか?

A. JavaScript の構文・組み込み機能(配列・文字列・Promise 等)はどちらでも同じです。違いは DOM API(ブラウザ専用)と fs などのファイル系(Node 専用)など、実行環境固有の機能です。コアロジックは両方で動くため、テストもしやすくなります。

Q. ES6 以降の新機能は使っても大丈夫ですか?

A. 現代のブラウザ・Node.js は ES2020 以降の機能をほぼサポートしています。古い IE 等を対象にする必要が無ければ、let/const、アロー関数、分割代入、async/await を積極的に使ってください。トランスパイル(Babel/Vite)が必要なケースは年々減っています。

Q. TypeScript に進む価値はありますか?

A. 型情報があるとリファクタやエディタ補完が劇的に効くため、規模が大きくなるなら TypeScript への移行を強くおすすめします。最初は any を許容しつつ徐々に型を付ければ、JS の知識をそのまま活かせます。

次のレッスン

次は for-in でオブジェクトを走査する で、配列の要素を直接取り出せる for-of 文を学び、配列内の最大値を求める関数を書こう を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. for-of の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. for-of とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 関数名は findMax、引数は数値の配列 numbers 1 つ、戻り値は数値
  2. 繰り返し処理には必ず for-of 文を使うこと (Math.maxfor ではなく)
  3. 配列が空でないことを前提としてよい (最低 1 つは要素がある)

入出力例

test-cases.txt

findMax([3,1,4,1,5,9,2,6])9 findMax([-3,-1,-10])-1 findMax([7])7 findMax([10,20,5,30,25])30

ヒント

main.js
main.js
学習モード

メモ

for-of で配列を走査する

⌘S で保存