JavaScriptのfor文のスコープ

JavaScriptのfor文の変数宣言部分の変数は、そのfor文と同レベル、for文の外と同じスコープに所属する。そしてJavaScriptはブロック文で新しくスコープを作らない。以上!

と分かってればそれで終わる話なんだけど、普段あんまりJavaScript書かないもので、思い出したように引っかかるのでもう少し書いておく。

var a = [];
for (var i = 0; i < 3; i++){
    a.push(function(){console.log(i);});
}

for (var j = 0; j < 3; j++){
    a[j]();
}

ってコードを書いて、表示としては0,1,2ってなるのを期待するんだけど、実際は3,3,3ってなる。
なぜなら冒頭書いたように、2行目のvar i = 0;はfor文の外で宣言したと同じで、その上のaと同じスコープに所属する。そしてその下のfunctionがバインドするスコープも同じく、そのa,iのあるスコープ。なのでここで作ったfunctionは結局おんなじiを見ていることになる。
1個目のfor文抜けたところでiは3になってるので、結果、作ったfunctionを呼んでもどれも同じく3を表示する。

うーんわかりやすく書こうと思ったけどあんまりだったわ。