かなり有名な話っぽいですけど、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 ループを使うほうがよいのです。
var arr = ["One", "Two", "Three"]; var i; for(i = 0; i < arr.length; i++){ console.log( [i, arr[i]].join(",") ); }