for of vs for in

What

for文におけるofとinの違い

for (let i = 0; i < xxx.length; i++)で書き直すことで、理解を深める。

Results

まず、用語の導入として、プロパティ名とプロパティを簡単に示します。

ハッシュでは、{プロパティ名: プロパティ}となります。
配列の場合は [プロパティ名]ですが、{配列の要素の番号: プロパティ名}とも見なせます。

const array  = ['yamada', '25', 12]
const hash = {0: 'yamada', 1: '25', 2: 12}

console.log(array[1] == hash[1])
// => true
console.log(array == hash)
// => false

inはプロパティ名を取得

for文でinを使うと、プロパティ名を取得できます。これは、ハッシュや配列、文字列にも適用できます。

const hashObject = {name: 'yamada', age: 25}
const str = 'avcde'

for (let key in hashObject){
    console.log(key)
    // => name age
}

for (let key in str){
    console.log(key)
    // => 0 1 2
}

次のようにも書き直せます。Object.keysメソッドは引数においたオブジェクトのキー (プロパティ名) を取得します。

const hashObject = {name: 'yamada', age: 25}
const str = 'avcde'

for (let i=0; i<Object.keys(hashObject).length; i++){
    console.log(Object.keys(hashObject)[i])
}

splitHash = str.split('')
for (let i=0; i<splitHash.length;i++){
    console.log(i)
}

ofはプロパティを取得

配列や文字列にしか使えません。

const hashObject = {name: 'yamada', age: 25}
const arrayObject  = ['yamada', '25', 12]
const str = 'abc'

for (let value of hashObject){
    console.log(value)
    // type error
}

for (let value of arrayObject){
    console.log(value)
    // => yamada 25 12
}

for (let value of str){
    console.log(value)
    // => a b c
}

for (let i=0; ...)での書き換えは、inでの書き換えと似ているため、省略します。ofの代わりに、forEachで書き直すこともできます。inとofはプロパティ名 (キー) を取り出したいのか、プロパティ (バリュー) を取り出したいのかで使い分けます。