for...inとfor...ofの違い


初めに

for...inとfor...ofの違いが曖昧だったのでまとめることにする。

for...in

for...inは指定されたれ連想配列(オブジェクト)から要素を取り出して先頭から順に処理する。

for_in.js
for( 仮変数 in 連想配列オブジェクト ) { 
   // 処理 
}

あくまでも出力されるのはキーであり、バリューではない。
なので、下記のようになる。

honda.js
var myTeam = {
    name: '本田',
    age: '33',
    birthplace: '大阪'
}

for( var item in myTeam){
    console.log(item);
} 

//name
//age
//birthplace

バリューを出したければ下記のようにする

honda2.js

var myTeam = {
    name: '本田',
    age: '33',
    birthplace: '大阪'
}

for( var item in myTeam){
    console.log( myTeam[item] );
}

//本田
//33
//大阪

注意点 配列をfor...in命令に利用してはならない

構文上使えないことはないのだが、prototypeで拡張されたメソッドまで引っ張ってきてしまう。

honda3.js

var team =['vvv', 'cska', 'milan'] //配列

for(var item in team){
    console.log( team[item] );
}

//vvv
//cska
//milan
honda4.js

var team =['vvv', 'cska', 'milan'] //配列
Array.prototype.hoge = function(){}  //プロトタイプで拡張

for( var item in team){
    console.log( team[item] );
}

//vvv
//cska
//milan
//ƒ (){}  //余計なもの

配列をfor...in命令に利用してはならない理由は他にもある
①for...in命令は処理の順序が保証されていない。
②仮変数(item)にはインデックス番号が格納されるだけなのでコードがシンプルにならない。

for...of

for...ofは配列などを順に処理する

for_of.js
for( 仮変数 of 列挙可能なオブジェクト ) { 
   // ループ内で実行する命令(群)
}

早速先ほどfor..inで行った処理をfor...ofに変えてやってみましょう。

honda4.js

var team =['vvv', 'cska', 'milan' ] //配列
Array.prototype.hoge = function(){}  //プロトタイプで拡張

for(var item of team){
    console.log(item);
}

//vvv
//cska
//milan

for...in命令では、仮変数にキー名(インデックス番号)が渡されていたのに対し、for...of命令では値が列挙されている。

おまけ

プロトタイプで拡張された場合でもfor...in命令を使いたい方は「オブジェクトが指定されたプロパティを持っているかどうかを判別する」hasOwnPropertyメソッドを使えば寄せぬ挙動を回避できる。

honda5.js
var team =['vvv', 'cska', 'milan' ] //配列

Array.prototype.hoge = function(){}
for( var item in team){
    if( team.hasOwnProperty(item) ) {
        console.log( team[item] );
    }
}

まとめ

for...in

・連想配列(オブジェクト)を操作する(配列を使ってはならない)
・値ではなく要素を出力する。
・prototypeで拡張すると意図せず出力されてしまう。

for...of

・列挙可能なオブジェクト(配列、NodeList、arguments等)を操作する。
・要素ではなくが出力される

参考

改訂新版JavaScript本格入門