2010年6月24日木曜日

javascriptのクロージャとローカル変数

javascriptのクロージャは下のどちらのタイプなのかを調べてみた
  1. クロージャの中から参照されているローカル変数のみ保持される (Perl Python型)
  2. 参照されているかどうかにかかわらず、アクセスできるすべてのローカル変数がクロージャの中でも保持される (Ruby型)


 どうやって調べるかというと、まずはPerlの場合
sub foo {
	my $bar = "bar";
	sub { eval shift };
}

print foo()->('$bar');
→ 結果:$barは出力されない


Pythonの場合
def foo():
	bar = "bar"
	def closure(ev):
		return eval(ev)
	return closure

print foo()("bar")
→ 結果:barは出力されない


Rubyの場合
def foo
	bar = "bar"
	lambda { |ev| eval ev }
end

print foo().call("bar")
→ 結果:barは出力される


という感じに、クロージャの中でevalしてやれば良いわけです。
それでは、javascriptはどうなるかというと

function foo() {
	var bar = "bar";
	return function(ev) { eval(ev) };
}

alert( foo()('bar') );
→ 結果:barは表示される
Firefoxで試したわけですが、IEでも同じように表示されることを確認。

個人的には、クロージャの中で参照されてる変数のみ保持してくれるほうが
オブジェクト解放のタイミングが直感的に分かりやすいから好きなんですけどね。
(実際の解放のタイミングは、GCの実装次第っていうのはありますが)
あと、PHPは苦手なので調べてません。

0 件のコメント:

コメントを投稿