#navi_header|JavaScript| "var"の機能について、以下の"ディノオープンラボ"でサンプルと共に解説されていたので、試してみる。 - "JavaScript の var についての考察" -- http://openlab.dino.co.jp/2007/09/20/20021368.html - "JavaScript: 変数+無名関数と関数リテラルの違い" -- http://openlab.dino.co.jp/2008/12/02/153231398.html 無名関数と関数リテラルについては置いておいて、単純なStringオブジェクトで試してみます。 #code||> baz = 'abc'; function(){ alert(baz); // (1) alerts 'undefined' var baz = 'def'; alert(baz); // (2) alerts 'def' }(); alert(baz); // (3) alerts 'abc' ||< 関数コードの中で *var* を使うと、実行スコープに *undefined* で *baz* という識別子が登録されます。 ですので(1)のalert()ではundefinedになります。(2)のalert()時点で、関数の実行スコープの *baz* には 'def' という値が入ってますので、それがalert()で表示されます。 (3)のalert()ですが、(1) - (2) で参照されている *baz* はあくまでも無名関数による実行スコープに登録されたものであって、グローバルスコープの *baz* は弄ってません。なので、最初に設定していた 'abc' がそのままalert()で表示されます。 で、試しに関数の中の var を取ってみます。 #code||> baz = 'abc'; function(){ alert(baz); // (1) alerts 'abc' baz = 'def'; alert(baz); // (2) alerts 'def' }(); alert(baz); // (3) alerts 'def' ||< こうすると関数コード中もグローバルスコープの *baz* を参照するようになるので、(3)でも変更後の値 'def' がalert()表示されます。 ちなみに実行スコープにより分断されるのは関数コードだけであって、一般的なBlock構文では実行スコープは生成されません。 #code||> foo = 'ABC'; { alert(foo); // (1) alerts 'ABC' var foo = 'DEF'; alert(foo); // (2) alerts 'DEF' } alert(foo); // (3) alerts 'DEF' ||< これについてはECMA262に記述されています。 #blockquote||> 12.2 Variable statement ... A Block does not define a new execution scope. Only Program and FunctionDeclaration produce a new scope. Variables are initialised to undefined when created. ||< #navi_footer|JavaScript|