Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

for...in の使い方

かなり有名な話っぽいですけど、JS初心者なのでメモっておきます。

以下のような for...in のループを書いてはいけません。

var arr = ["One", "Two", "Three"];
var i;
for(i in arr){
	console.log( [i, arr[i]].join(",") );
}


例えば、 prototype.js を読み込んだ状態ですと、以下のような残念な結果となります。

0,One
1,Two
2,Three
each,function (iterator, context) { var index = 0; iterator = iterator.bind(context); try { this._each(function (value) {iterator(value, index++);}); } catch (e) { if (e != $break) { throw e; } } return this; }
eachSlice,function (number, iterator, context) { iterator = iterator ? iterator.bind(context) : Prototype.K; var index = - number, slices = [], array = this.toArray(); while ((index += number) < array.length) { slices.push(array.slice(index, index + number)); } return slices.collect(iterator, context); }
... 以下略 ...

これは、 Array.prototype が持つものも、 for..in によって拾ってしまうためです。これを防ぐには、以下のようにコーディングします。

var arr = ["One", "Two", "Three"];
var i;
for(i in arr){
	if( ! arr.hasOwnProperty(i) ) continue;
	console.log( [i, arr[i]].join(",") );
}

なお、今回のように対象が配列である場合に関して言えば、一番いいのは以下のようにfor..inは使わないことです。

配列に対して反復するときは、数値的な添え字を用いた伝統的な for ループを使うほうがよいのです。

Core JavaScript 1.5 Reference

var arr = ["One", "Two", "Three"];
var i;
for(i = 0; i < arr.length; i++){
	console.log( [i, arr[i]].join(",") );
}