【javascript】for-in, for-ofの挙動と使い方
はじめに
以前にforEach文の使用について調査して以降、for-in
, for-of
を使用しておきながら、細かい仕様をすっかり忘れてしまっていたので、勉強も兼ねてまとめてみる。
内容
まず、for-in
、for-of
についての概要を説明する。
for-in
は連想配列に対し、その「プロパティ」を順番に取り出す。
for-of
は列挙可能なオブジェクト(配列など、値が順番に並んでいる様なオブジェクト)に対し、その「値」を順番に取り出す。
let memberObj = {
name: '田中',
age: 16,
from: '東京'
};
for( const key in memberObj ){
console.log(key);
}
// 結果:
// name
// age
// from
let memberList = ['田中', '佐藤', '小林'];
for( const val of memberList ){
console.log(val);
}
// 結果:
// 田中
// 佐藤
// 小林
詳細
ここからが本番で、どのような場面でどちらを使うかを私の観点で書いてみる。
配列をループさせたい場合
値だけ取り出したいなら、for-of
。コードは割愛。
値に加えてインデックス(添え字)を取得したいのであれば、単純なfor文でもよいが、for-of
も使える。
let memberList = ['田中', '佐藤', '小林'];
for (const [idx, member] of memberList.entries()) {
console.log(`${idx} : ${member}`);
}
// 結果
// 0 : 田中
// 1 : 佐藤
// 2 : 小林
この場合はfor-in
は基本使わないし、使う必要もない。なぜならfor-of
で事足りているため。
なぜfor-in
を使わないかを書くととても長くなってしまうため、当記事では割愛。どうしても知りたい方はこちらの方の記事を参照いただきたい。
→配列にfor...inはダメと言うけれど、
最後の方に出てきた、memberList.entries()
のentries()
については後でまとめて解説する。
余談だが、この時の... const [idx, member] of ...
は何故const
を使っているのか疑問に持つ方もいるかもしれないので簡単に書いておくと、ループするたびにスコープが閉じて新しいスコープになるイメージ。
なので、直感的にはだめそうに見えるが実は可能。むしろfor-of
であれば積極的にconst
を使う方が、「あ、ループ内ではこの値は不変なんだな」と認識され、可読性が高まる(ことが多い)。
連想配列をループさせたい場合
キーだけ取り出したいならfor-in
。ただそういう場面は限られていそうだし、基本はfor-of
。
let memberObj = {
name: '田中',
age: 16,
from: '東京'
};
// 1
for ( const key in memberObj) {
console.log(`${key} : ${memberObj[key]}`);
}
// 2
for ( const [key, member] of Object.entries(memberObj)) {
console.log(`${key} : ${member}`);
}
// 結果(1,2共に同じ結果となる)
// name : 田中
// age : 16
// from : 東京
ここでentries()
について説明しておく。
先ほど出てきた[配列].entries()
は、こんな配列([a, b, ...]
)を[0, a], [1, b] ...
の形式で順番に返す。
次に、今出てきたObject.entries([連想配列])
は、こんな連想配列({a:xxx, b:yyy, ...}
)を[a, xxx], [b, yyy], ...
の形式で順番に返す。
お察しの通り、前者は配列。後者は連想配列に対して使用する。細かく言うと後者は配列にも使えるけど、素直に使い分けたほうが配列と連想配列のどっちを使っているか見分けやすいので、なるべく使い分けよう。
まとめ
- 配列の値だけ取り出す →
for-of
- 配列の添え字と値を取り出す →
for-of
、シンプルなfor
- 連想配列のキーだけ取り出す →
for-in
- 連想配列のキーと値を取り出す →
for-of
もう皆様お気づきだろうが、基本for-of
で何でもできる。ぜひfor-of
を有効活用していこう。
Discussion