2009年06月05日

JavaScriptの変数の面白い特性――グローバルな変数はundefined??

これは驚き。もしかしたら日頃JavaScript弄ってる人にとっては常識なのかもしれないけど、俺は凄く驚いた。

先ずは以下のコードを。


<html>
	<head>
		<script type="text/javascript">
			// <![CDATA[
			var hoge = 'hoge global';
			var piyo = 'piyo global1';

			if(piyo == undefined) {
				var piyo = 'piyo global2';
			}

			function f1() {
				var elem = document.getElementById('elem');

				elem.innerHTML = elem.innerHTML + '<br />' + piyo;
			}

			function f2() {
				var elem = document.getElementById('elem');

				elem.innerHTML = elem.innerHTML + '<br />' + hoge;
			}

			function f3() {
				var elem = document.getElementById('elem');

				if(hoge == undefined) {
					var hoge = 'hoge local';
				}

				elem.innerHTML = elem.innerHTML + '<br />' + hoge;
			}

			// ]]>
		</script>
	</head>
	<body>
		<p id="elem"></p>
		<script type="text/javascript">
			// <![CDATA[
			f1();
			f2();
			f3();
			// ]]>
		</script>
	</body>
</html>

で、この実行結果は、こうなる。


piyo global1
hoge global
hoge local

f1()は、続くf2()f3()との比較の為に書いているに過ぎない。ここで見て欲しいのはf2()f3()の実行結果の違いだ。

そう、グローバル領域で初期化している変数が、関数内ではundefiendと等価である、と評価されている

f1()

順に見てみる。先ずはf1()


var piyo = 'piyo global1';

if(piyo == undefined) {
	var piyo = 'piyo global2';
}

function f1() {
	var elem = document.getElementById('elem');

	elem.innerHTML = elem.innerHTML + '<br />' + piyo;
}

グローバル変数piyoを初期化。その直ぐあと、関数の外でpiyoundefinedか判定。当然、偽となるので改めて初期化されることはない。結果、f1()では最初に初期化した時の内容であるpiyo glocal1が出力される。

f2()


var hoge = 'hoge global';

function f2() {
	var elem = document.getElementById('elem');

	elem.innerHTML = elem.innerHTML + '<br />' + hoge;
}

単純にグローバル変数hogeを出力している。問題なくhogeの値であるhoge globalが出力されていることに注意。つまり、(当たり前のことだが)関数内からグローバル変数の値を評価できている。

f3()


var hoge = 'hoge global';

function f3() {
	var elem = document.getElementById('elem');

	if(hoge == undefined) {
		var hoge = 'hoge local';
	}

	elem.innerHTML = elem.innerHTML + '<br />' + hoge;
}

グローバル変数hoge(これはf2()で用いたものと同じ変数)を出力する前に、グローバル変数hogeundefiendでないかを評価、それが真ならば改めてhogeを(グローバルでとは別の値で)初期化している。そして、驚くべき事にこの評価式は真となっている。確かにグローバル領域で初期化しているのに!

f2()での結果を見ると、確かに初期化され、値を評価できているグローバル変数だが、f3()での結果によると、初期化されていないという評価を下されている事が分かる。言ってみれば、グローバル変数が、関数内ではundefinedと実際の値という2つの値を持っているかのようだ。

因みに、この動作は手持ちの以下のブラウザで確認した。すべでこの動作だった。(全てWindows用。Safariを除いて全て日本語版)

  • Mozilla Firefox 3.0.10
  • Opera 9.6.4 Build 10487
  • Safari 4 Public Beta (528.16)
  • Microsoft Internet Explorer 8.0.6001.18702

一体全体、これはどういう事なのだろうか。

ラベル:javascript
posted by 天井冴太 at 05:09| Comment(3) | TrackBack(0) | Study | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は180日以上新しい記事の投稿がないブログに表示されております。