with と catch のスコープ

with と catch はスコープが変わる、と思ってたけど function とは全然違うのね。

var spam;
alert(spam) //undefined
var obj = {};
with(obj){
    var spam;
    spam = "inside of with block";
};
alert(spam); //"inside of with block"

with ブロックの中で var spam してもブロック内オンリーな spam ができる訳でもなく spam に代入した文字列は global に戻ってもそのまま。
ちゃんと仕様書を見てみたら
http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/12_Statements.html#section-12.10

with 文は現在の実行コンテキストのスコープ連鎖の先頭に算出されたオブジェクトを追加し、この拡張されたスコープ連鎖を用いて文を実行し、スコープ連鎖を蓄積する。

てことらしい。catch も似たようなもんらしい。

つまり宣言された identifier を集めるときは放っといていいけど、どっかで有効な identifier のリストを作ろうとするといちいち (with|catch) の中かどうか判定して、そうなら適当なスコープつくってスコープチェインの頭にくっつけにゃならんのか。


おまけ。

with(["hoge", "fuga"]){
    alert(1);
};

とかしてみたけどやっぱ無駄だった。できても困るけど。