今回の記事ではJavaScriptのObject(オブジェクト)のループのやり方を3つ紹介します。
配列と違ってJavaScriptのオブジェクトってどうやるんだろう?
PHPだと連想配列のための「foreach」、RubyだとHashのための「each」があるけどJavaScriptにはそれに該当するものないの?
普段JavaScriptを使われていない方や、プログラミングを学び始めた初心者の中にはこのように思われている方も多いのではないでしょうか?
JavaScriptのオブジェクトのループ処理の方法はいろいろありますが大きく分けると次のようになります。
- オブジェクト(Object)のままループを行う
- 配列(Array)に変換してループを行う
- 外部ライブラリを使ってPHPのforeach, Rubyのeachの機能を実現する
それでは上記3つの方法について詳しく説明していきます。
目次
オブジェクト(Object)のままループを行う
オブジェクトをループする方法は「for in」を使うことです。
実際にサンプルコードを使って説明します。
1 2 3 4 5 6 7 8 9 10 11 |
const person = { name: 'つよぽん', gender: '男', hobby: '筋トレ' }; for (let prop in person) { console.log('propの値: ', prop); console.log('person[prop]の値: ', person[prop]); console.log('---------------------------'); } |
それぞれ1行ごとに何をやっているのか説明します。
まず1行目の「const person」でオブジェクトを定義しています。今回はぼくの個人情報をセットしました^^
7行目で「for in」を使ってループ処理を行っています。「for in」の使い方は通常のforループと異なり次のように定義します。
for (変数宣言 in オブジェクト)
- 変数宣言 : 上記コードの7行目の「let prop」の部分。propの中に「’name’」「’gender’」「’hobby’」という文字列が代入されていきます。
- オブジェクト : 上記コードの7行目の「person」の部分。
そして8行目には「person」オブジェクトのプロパティである、「’name’」「’gender’」「’hobby’」がループ毎に出力されていきます。
9行目ではオブジェクトに保持されている特定の値を取得するために次の形式で、各プロパティに対応する値を取得しています。
- person[“プロパティ名”]
JavaScriptでオブジェクトの特定のプロパティに対応する値を取得する方法は以下の2通りあります。
- person.name
- person[‘name’]
1つ目 も2つ目も「name」プロパティの値を取得するやり方です。
しかし次のように書いた場合はどうなるでしょうか?
- person.prop
- person[prop] (「”」(クオーテーションマーク)で囲われていないことに注意)
1つめの「person.prop」は、「prop」とプロパティ名で値を探そうとします。しかし、「person」オブジェクトには「prop」というプロパティが存在しないので「undefined」が返ってきます。
2つめの「person[prop]」の場合は、「prop」には「’name’」「’gender’」「’hobby’」という値が入るので、「’name’」のときには「person[‘name’]」となり「つよぽん」が返ってきます。
上記コード内容を実際にChromeのデベロッパーツールを使って出力した内容が以下の画像になります。
person[prop]で出力した結果
person.propで出力した結果
「for in」を使うときは上記注意点でも説明したように値の出力方法に気をつけていただけたらと思います。
配列(Array)に変換してループを行う
次はオブジェクトを配列に変換してループする方法を説明します。
オブジェクトを配列に変換するやり方は次の2通りあります。
- Object.keysを使う
- Object.valuesを使う (※比較的新しい機能であるため対応していないブラウザも多い)
Object.keys
「Object.keys」はオブジェクトのプパティ(キー)の一覧を取得するメソッドです。
次のサンプルコードを使いながら説明します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const person = { name: 'つよぽん', gender: '男', hobby: '筋トレ' }; const props = Object.keys(person); console.log('propsの値: ', props); console.log('====================='); props.forEach(prop => { console.log('propの値: ', prop); console.log('person[prop]の値: ', person[prop]); console.log('-----------------------'); }); |
それぞれの行で何をやっているか説明します。
1行目は先程の「for in」と同じように「person」オブジェクトを定義しています。
そして、7行目で今回説明している「Object.keys」を使って「person」のプロパティ一覧を取得して、「props」変数に代入しています。
次の画像は上記コードの出力結果です。
propsは配列であるため、Arrayメソッドの1つである「forEach」を使うことが出来ます。
もちろん「forEach」を使わなくても「for (let i = 0; i < props.length; i++) {…}」のように通常のfor文でループすることも可能です。
通常の「for」ループ以外でに配列をループするやり方を知りたい方は次の記事も参考にしていただけたらと思います。
Object.values
「Object.values」は「Object.keys」とは逆で、各プロパティに対応する値の一覧を取得するメソッドです。
ただし、このメソッドは注意が必要で、比較的新しく用意されたメソッドであるため「Object.values」が使えないブラウザも存在します。
その観点からいうとしばらくは「Object.values」は使わず「Object.keys」を使ったほうが無難でしょう。
今回「Object.values」を紹介する理由は、将来的に全てのブラウザで対応されたら便利なメソッドなので覚えておいて損はないなと思い紹介することにしました。
それでは実際にサンプルコードを使って説明します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
const person = { name: 'つよぽん', gender: '男', hobby: '筋トレ' }; const values = Object.values(person); console.log('valuesの値: ', values); console.log('====================='); values.forEach(value => { console.log('valueの値: ', value); console.log('-----------------------'); }); |
先ほど紹介した「Object.keys」のサンプルコードとの異なる点は以下の2箇所です。
- 7行目が「Object.keys」→「Object.values」に変更した
- 「Object.keys」の13行目に書かれてた「console.log(‘person[prop]の値: ‘, person[prop]);」が削除された
2つ目のように、「person[prop]」のようにオブジェクト(今回の場合は「person」)を使う必要がなくなるので、値の一覧だけを取得したい場合は、Object.valuesを最初から使うと便利になります。
実際に上記サンプルコードの実行結果は以下の画像になります。
外部ライブラリを使ってPHPのforeach, Rubyのeachの機能を実現する
PHPやRubyを普段のお使いの方であれば、「PHPの「foreach」や、Rubyの「each」に該当するものはあったら便利なのになあ」と思われてる方もいらっしゃるかと思います。
JavaScriptでも同じような機能を実現するためには外部ライブラリを利用すれば可能となります。
そのライブラリは「Lodash」と「Underscore」です。
どちらも基本的に同じことが出来る機能なのでどちらか片方を選択すれば良いです。
選ぶ基準ですがGithubの人気度を表す「Star(星)」の数を見ると「Lodash」が約34000、「Underscore」が約24000と「Lodash」のほうが人気が高いので「Lodash」を選ぶと良いでしょう。(2018年9月6日現在)
それでは早速Lodashを使った場合のサンプルコードを使って説明します。
1 2 3 4 5 6 7 8 9 10 11 |
const person = { name: 'つよぽん', gender: '男', hobby: '筋トレ' }; _.forEach(person, (value, key) => { console.log('keyの値: ', key); console.log('valueの値: ', value); console.log('-----------------------'); }); |
上記サンプルコードの7行目が「Lodash」を使ったオブジェクトのループ処理になります。
今回は「_.forEach」メソッド利用しました。これはPHPの「foreach」、Rubyの「each」と同等の機能を持ちます。
_.forEachメソッドが受け取る引数は次のとおりです。
- 第1引数 : オブジェクト(今回の場合は「person」オブジェクト)
- 第2引数 : コールバック関数
また、第2引数のコールバック関数が受け取る引数は次のとおりです。
- 第1引数 : 値(value)。今回だと「’つよぽん’」「’男’」「’筋トレ’」が入る
- 第2引数 : キー(key)。今回だと「’name’」「’gender’」「’hobby’」が入る
※コールバック引数の順番は「key」→「value」の順番ではなく、「value」→「key」の順番であることに注意。
次の画像は「Lodash」の「forEach」メソッドを使った実行結果になります。
PHP、Rubyを普段使っている方の場合はこちらのほうが使いやすいのではないかと思います。
まとめ
ここまで話してきた内容をまとめると以下のようになります。
- 「for in」を使ってループ処理を行う
- 「Object.keys」「Object.values」を使ってオブジェクトを配列に変換 → Arrayメソッドや通常の「for」ループを使う
- 「Lodash」と「Underscore」と言った外部ライブラリを使ってループ処理を行う
オブジェクトの中身をループさせたいなと思う場面は開発中に何度も遭遇するかと思います。
オブジェクトのループのやり方が分からなかった方、他にどんなやり方があるのか知りたかった方は上記を参考にしていただけたらと思います。