Array, Object, String × for...in, for...of
配列も、オブジェクトも、文字列も、 for 文で回せるのが JavaScript のいいところなんだけど、in と of の2種類があって、どっちがどっちなのか忘れちゃうので、自分のためのチートシートを作った。
for | Array | Object | String |
---|---|---|---|
in | index | key | index |
of | value | SyntaxError | value |
追記:結論を書いちゃうと、
「いん」は「いんデックス」
「おぶ」は「ぶぁりゅ~」
と覚えればこのページを見なくても生きていける(ぉぃ
Array + in -> index
for ( const i in [ 111, 222, 333 ] ) // Array + in -> index
{
console.log( i ) // '0' '1' '2'
}
ここでの注意点は、なんとi
には数値(number)ではなく数字(string)がくるところ(なんでやねん!まぁ、気にせず計算はできちゃうんだけどね)
Array + of -> value
for ( const v of [ 111, 222, 333 ] ) // Array + of -> value
{
console.log( v ) // 111 222 333
}
index value 両方を得たい場合はこうするしかなくて
const ary = [ 111, 222, 333 ]
for ( const i in ary )
{
console.log( i, ary[i] ) // 0 111 1 222 2 333
}
であれば手っ取り早いのは .forEach()
なんだけど、
[ 111, 222, 333 ].forEach( (v,i)=> // value, index の順番
{
console.log( i, v ) // 0 111 1 222 2 333
} )
でも、.forEach()
使うくらいなら、 .map()
を使うかなぁ。
なんというか、戻り値を使わないのがもったいなくて。貧乏性?
console.log(
[ 111, 222, 333 ].map( (v,i)=>[i,v] )
) // [ [ 0, 111 ], [ 1, 222 ], [ 2, 333 ] ]
range()
残念ながら、いまの JavaScript には他の言語に見られるような便利な range() は無いようです。
代わりに以下のようなコードが使われているようです。for...in なのか for...of なのかわかりにくいですよね。
for...in を使いたい場合はこう書いて、
for ( const i in Array.from(Array(5)) ) // Array + in -> index
{
console.log( i ) // '0' '1' '2' '3' '4' 注意:文字
}
for ( const i in Array(5) )
ではダメなんです、謎。(これをおっけーにしてほしいなぁ、、、お願いします🙏)
for...of を使いたい場合は、
for ( const v of Array(5).keys() ) // Array + of -> value
{
console.log( v ) // 0 1 2 3 4 注意:数値
}
こっちのほうが数値だし、短くてよさげですが、この書き方だと in はダメで of ならおっけーってところが解せない感じ。ちょっと覚えにくいし、どっちもパッと見て直感的にどう動くのか理解できないと使えないと思うんですよね。
Object + in -> key
for ( const k in { a: 111, b: 222, c: 333 } ) // Object + in -> key
{
console.log( k ) // a b c
}
Object + of -> SyntaxError
実行できません
for ( const v of { a: 111, b: 222, c: 333 } ) // Object + of -> SyntaxError
{ ^^
console.log( v ) //
}
両方ほしいときは、まぁ、こうするかな。
const obj = { a: 111, b: 222, c: 333 }
for ( const k in obj )
{
console.log( k, obj[k] ) // a 111 b 222 c 333
}
もしくは、
const obj = { a: 111, b: 222, c: 333 }
Object.keys( obj ).forEach( k=> // [ 'a', 'b', 'c' ]
{
console.log( k, obj[k] ) // a 111 b 222 c 333
} )
String + in -> index
for ( const i in 'abcあいう' ) // String + in -> index
{
console.log( i ) // '0' '1' '2' '3' '4' '5'
}
String + of -> value
for ( const v of 'abcあいう' ) // String + of -> value
{
console.log( v ) // 'a' 'b' 'c' 'あ' 'い' 'う'
}
残念ながら、以下のようには書けなくて、
'abcあいう'.forEach( (v,i)=> // TypeError: .forEach is not a function
{
console.log( i, v )
} )
.split('')
を使って回避することはできる。しかし、空の文字列で分割って、、、、どうなんだろう。
'abcあいう'.split('').forEach( (v,i)=> // value, index の順番
{
console.log( i, v ) // 0 a 1 b 2 c 3 あ 4 い 5 う
} )
以下、参考