JavaScriptのfor文がややこしい。
ややこしいので忘れたときのためにメモ。主に配列を走査するとき。
for inで配列の走査してはダメ
Array.prototype.hoge = function() {}; for (var i in ['a', 'b', 'c']) { console.log(i); // 0, 1, 2, hoge が表示される }
for in はオブジェクトのプロパティを走査する記法だから、プロトタイプが拡張された場合に対応出来ない。
forまたは後述のforEachで書くべし。
forEachでできるけど...
breakは使えなくて、continueはreturnとなる。
古いプラウザでは動かないらしいのでそれも注意。
['a', 'b', 'c'].forEach(function(i) { console.log(i); // a, b, cが表示される });
配列の走査でbreakを使いたいときは
普通にforで書くか、someを使うか、each(jQuery)を使うとかする。
someを使う
valueとindexを返すので、Pythonのenumerate的な使い方もできる。
ただし、Pythonのenumerateではindex, valueの順だけどsomeでは逆となる。
[1,2,3,4,5].some(function(v,i){ console.log(v,i); return v > 2; // 2より大きいvに当たればbreak }); /* 1 0 2 1 3 2 が表示される */
each(jQuery)を使う
trueがcontinueに、falseはbreakになる。
var arr = [1, 2, 3, 4, 5] $.each(arr, function() { if (this < 3) { console.log(this); return true; // continue } else { return false; // break } }); //1, 2が表示される。
eachは連想配列でも使える。連想配列はPythonで言うdict。
var dict = {one: 1, two: 2, three: 3, four: 4, five: 5} $.each(dict, function(i, v) { if (v < 3) { console.log(i, v); return true; // continue } else { return false; // break } }); /* one 1 two 2 が表示される */
連想配列はfor in使ってOK
var dict = {hoge: 'hoge', fuga: 'fuga'} for (var i in dict) { console.log(dict[i]); // hoge, fugaが表示される。 }
多重forループにはラベルを使う
ラベルを使うと、breakとかcontinueが楽になる。
L: for(var i = 0; i < 3; i++){ for(var j = 0; j < 3; j++){ console.log(i, j); if(i == 1 && j == 1) break L; } } /* 0 0 0 1 0 2 1 0 1 1 と表示される */