主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

JavaScriptのクロージャ(おまけ:Pythonのジェネレータ)

                
tags:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title> 関数クロージャ</title>
<script type="text/javascript">
function outer(){
var x = 1;
function incr(){
alert(x);
x = x + 1;
};
return incr;
}

var f = outer();
f(); // 1
f(); // 2
f(); // 3
</script>
</head>
<body>
<p>...</p>
</body>
</html>



上のスクリプトを走らせてみて、出力を見たら「なんで?」と思った。というわけでメモメモ。

要はクロージャを使って関数内の値を保持して、その保持した値にインクリメントを行って出力していくというやつ。クロージャの特徴である(らしい)、関数内で値を保持するという特徴をまんま表したもの。

このスクリプトを走らせた結果を見て僕の脳みそは、なぜーだーと思ってしまった。f()を実行するたびに"1"って出てくるんじゃないのって。そんで動作をよく考えてみた。そしたら納得いった。

まず関数outerが定義され、中の関数も定義される。そして最初にf()を呼ぶ。fには"return incr"によって関数incrへのポインタが入っているから、outer内の他の式や関数は実行されず、ただincr()だけが行われる。そういうことなんだなと。

Pythonのジェネレータでこれと似たことをしたなぁ。やってみよう。つまり関数内でのローカル変数の値を保持したまま出力していくというもの。

def incr():
num=0

while True:
num += 1
yield num


x=incr()
print next(x)
print next(x)
print next(x)
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。