【JavaScript】for...in文の書き方と使い方の基本
JavaScriptの繰り返し構文であるfor...in文の基本的な書き方と使い方を解説します。オブジェクトが持つプロパティの「キー」を順番に取り出し、それに対応する「値」を取得する方法を学びます。サンプルコードを通して、初心者にも分かりやすく実践的な使い方を説明します。
開発環境
- OS: Windows10
- Editor: Visual Studio Code
- JavaScript: ES6以降
JavaScriptのfor...in文とは
for...in文は、オブジェクトが持つプロパティの「キー」を一つずつ順番に取り出して、繰り返し処理を行うための構文です。
オブジェクトとは、{キー: 値} のように、名前(キー)と値がペアになったデータを複数格納できるものです。for...in文を使うと、この「キー」の部分をループ処理で取得できます。
for...in の書き方
for...in文は、オブジェクトが持つプロパティ名(キー)を一つずつ順番に取り出し、繰り返し処理を行うための構文です。オブジェクトに含まれるすべてのプロパティに対して、何らかの処理をしたい場合に使用します。
1for (変数 in オブジェクト) { 2 // 各プロパティ名(キー)ごとに実行される処理 3}
この構文の各部分について説明します。
-
変数ループが一周するごとに、オブジェクトから取り出されたプロパティ名(キー)が文字列として格納されます。この変数名は自由に決めることができます。 -
オブジェクト繰り返し処理の対象となるオブジェクトを指定します。 -
{}内の処理 取り出したプロパティ名(キー)を使って実行したい処理を記述します。この処理は、オブジェクトが持つプロパティの数だけ繰り返されます。
サンプルコード
ここでは、JavaScriptのfor...inループについて学習します。for...inループは、主にオブジェクトの各プロパティに対して繰り返し処理を行うために使用されます。これから紹介するサンプルコードを通して、その使い方を具体的に見ていきましょう。
javascript/chapter13/index.html
1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 6 <title>JavaScriptチュートリアル</title> 7 </head> 8 9 <body> 10 <h1>JavaScriptチュートリアル</h1> 11 <script src="./script01.js" defer></script> 12 <script src="./script02.js" defer></script> 13 <script src="./script03.js" defer></script> 14 <script src="./script04.js" defer></script> 15 </body> 16</html>
このHTMLファイルは、これから説明する4つのJavaScriptファイルを読み込んで実行するためのものです。<body>タグの最後にある<script>タグが、それぞれのJavaScriptファイルを指定しています。ブラウザでこのHTMLファイルを開くと、JavaScriptの実行結果を開発者ツールのコンソールで確認できます。
javascript/chapter13/script01.js
1// オブジェクトをfor...inでループする基本例 2const user = { 3 name: "太郎", 4 age: 25, 5 gender: "male", 6}; 7 8for (let key in user) { 9 console.log(`${key}: ${user[key]}`); 10} 11 12// 出力: 13// name: 太郎 14// age: 25 15// gender: male
これはfor...inループの最も基本的な使い方です。
userという名前の「オブジェクト」が定義されています。オブジェクトは、nameやageのような「キー」と、"太郎"や25のような「値」をペアで保持するデータ構造です。
for (let key in user)の部分でループ処理が始まります。このループでは、userオブジェクトが持つキー(name, age, gender)が、一つずつ順番に変数keyに代入されます。
ループの中では、user[key]という形で、現在のキーに対応する値を取得しています。例えば、keyが"name"のとき、user["name"]は"太郎"という値になります。これをconsole.logで出力することで、オブジェクトの中身をすべて表示しています。
javascript/chapter13/script02.js
1// 配列に対してfor...inを使う例(非推奨だが可能) 2const fruits = ["apple", "banana", "cherry"]; 3 4for (let index in fruits) { 5 console.log(`index ${index}: ${fruits[index]}`); 6} 7 8// 出力: 9// index 0: apple 10// index 1: banana 11// index 2: cherry
for...inループは配列に対しても使用できますが、この方法は一般的に推奨されません。
fruitsという名前の「配列」が定義されています。配列は、複数の値を順番に格納するデータ構造です。
配列に対してfor...inループを使用すると、変数indexには配列の値("apple"など)ではなく、その値が格納されている位置を示す「インデックス」(0, 1, 2...)が文字列として代入されます。
ループの中では、fruits[index]とすることで、各インデックスに対応する値を取得して出力しています。配列の繰り返し処理には、より適したfor...ofループやforEachメソッドなどがあるため、そちらを使うのが一般的です。
javascript/chapter13/script03.js
1// ネストされたオブジェクトをfor...inでループ 2const product = { 3 id: 101, 4 name: "ノートパソコン", 5 spec: { 6 cpu: "Core i7", 7 ram: "16GB", 8 storage: "512GB SSD", 9 }, 10}; 11 12console.log("商品情報:"); 13 14for (let key in product) { 15 if (typeof product[key] === "object") { 16 console.log(`${key}:`); 17 for (let subKey in product[key]) { 18 console.log(` ${subKey}: ${product[key][subKey]}`); 19 } 20 } else { 21 console.log(`${key}: ${product[key]}`); 22 } 23} 24 25// 出力: 26// 商品情報: 27// id: 101 28// name: ノートパソコン 29// spec: 30// cpu: Core i7 31// ram: 16GB 32// storage: 512GB SSD
この例では、オブジェクトの中に別のオブジェクトが含まれている、入れ子(ネスト)構造のデータをfor...inループで処理しています。
productオブジェクトのspecというキーの値は、それ自体がCPUやRAMの情報を持つ別のオブジェクトになっています。
外側のfor...inループでproductオブジェクトの各プロパティを調べ、if (typeof product[key] === "object")という条件文で、値がオブジェクトかどうかを判定しています。
- 値がオブジェクトの場合(
specのとき)、キーの名前だけを表示し、さらにもう一つのfor...inループ(内側のループ)を使って、そのオブジェクトの中身を一つずつ出力します。 - 値がオブジェクトでない場合(
idやnameのとき)は、これまで通りキーと値をそのまま出力します。
このようにfor...inループを組み合わせることで、複雑なデータ構造も扱うことができます。
javascript/chapter13/script04.js
1// 練習問題:生徒の得点データから教科名と点数を出力する 2const scores = { 3 国語: 80, 4 数学: 75, 5 英語: 90, 6 理科: 70, 7 社会: 85, 8}; 9 10let total = 0; 11 12for (let subject in scores) { 13 console.log(`${subject}の点数: ${scores[subject]}点`); 14 total += scores[subject]; 15} 16 17const average = total / Object.keys(scores).length; 18console.log(`合計点: ${total}点`); 19console.log(`平均点: ${average}点`);
これはfor...inループを使った実践的な練習問題です。生徒の各教科の点数が格納されたscoresオブジェクトを処理します。
まず、合計点を保存するための変数totalを0で初期化します。
次に、for...inループを使ってscoresオブジェクトのキー(教科名)を一つずつ変数subjectに取り出します。ループの中では、以下の2つの処理を行っています。
console.logで各教科名と点数(scores[subject]で取得)を出力します。total += scores[subject]という記述で、取り出した点数をtotal変数に加算していきます。
ループがすべて終了すると、totalには全教科の合計点が入っています。
最後に、合計点を教科数で割って平均点を計算しています。Object.keys(scores).lengthは、scoresオブジェクトのキーの数(この場合は5)を取得するための記述です。算出した合計点と平均点をコンソールに出力して処理は完了です。
おわりに
この記事では、for...in文がオブジェクトの「キー」を順番に取り出すための構文であることを学びました。取り出したキーを オブジェクト[キー] のように記述することで、対応する値を簡単に取得できます。この仕組みを使えば、オブジェクトのデータを一覧表示したり、合計値を計算したりすることが可能です。配列の繰り返しにはfor...of文など他の方法が適していますが、オブジェクトを扱う際にはfor...in文が非常に役立ちます。