プログラミングの整理簿 > Javascriptプログラミング > 7 クロージャと高階関数 なれば、其処には更に詳細が、又他にも有用な記事が揃えば、 偶々此方に漂い付いた方も真に解決法を求れば其方を参照いただきたく思います。 また、IT戦記のamachang氏も2008年2月8日の記事 jQuery(document).ready(function($) {})() と function(){}() に自分用メモとして関連した覚書をされ、 bkブログでは高林氏が2005年7月23日の記事 JavaScript とクロージャ で水彩画と云うか、水墨画と云うか、当該事項を用いたサンプルプログラムを公開され面白く、 共に参考になるかと思います。
スポンサーリンク
- 関数式
var foo = function (n) { return n * 2; };引数nに3を与える。
- クロージャ
var x = 1;「"a()=" + a()」を順に3回実行する。
function Counter() {
var n = 0;
return function () {
n = n + x;
return n;
};
}
var a = Counter();
var b = Counter();
a及びbの値が保持されることを示すため以下- "a()=" + a()
- "a()=" + a()
- "b()=" + b()
- "a()=" + a()
- "b()=" + b()
即ちクロージャとは単なる関数ではなく、その関数が定義された環境への参照を持った関数のことです。ここでいう環境とは変数とスコープです。
であることでa及びbは此のWebページを開いている間、保持されてしまう為、初期化する。
此処に表示される右辺がa及びbが参照しているクロージャであり、 其れを初期化する処理を施したことになる。
javascriptに於けるクロージャの更なる詳細を以下に引用する。Javascriptでは関数はクロージャになります。そして関数と環境は次のような関係があります。
試みにグローバル変数のxを変化させる。x=1は初期化にあたる。- 関数は定義されたときの環境を保持する。
- 関数が実行されるときに新たな環境(ローカル環境)が生成される。
- 変数へのアクセスが関数の内部で解決されない場合、関数の保持する環境で解決される。
此の後、sample2、sample3を実行すると、引用に依るJavascriptのオブジェクトはそれを参照するモノ(変数やオブジェクト)がなくなると解放されます。環境も同様で、通常は関数の実行が終了すると解放されますが、クロージャが参照している環境は存在しつづけることになります。
が分かり易い。 - 高階関数
高階関数とは関数(クロージャ)を引数に取る関数、または戻り値として関数(クロージャ)を返す関数のことです。
function each(s, e, func) {このeachでは三番目の引数の順次整数を加算する関数がクロージャであり、 一番目の引数から二番目の引数迄を実行する。 関数eachを実行し、順次増加する整数を3回アラート表示する。
for (var i = s; i <= e; i++) {
func(i);
}
}
each(1, 3, function (n) {
alert(n);
});
function foo2() {
var x = 0
each(1, 10, function (n) {
x += n;
});
alert(x);
}ここで関数each()の3番目の引数に渡されるクロージャが定義された環境は関数foo()の内部になります。変数xへのアクセスは関数foo()の内部の環境で解決されます。
1から10迄整数を加算する。
- 初期化機能付き関数
(function (n) { alert(n); })(7);上のコードを直接実行する。
このコードは以下と同等である。var foo = function (n) { alert(n); };即ち
foo3(7);前者の例では、関数を定義するとともにその場で実行して
いる。引き続き引用のこの性質とクロージャとしての性質を利用することで内部で何らかの初期化を行いクロージャを返す関数を作ることができ
るとされ、其のサンプルたるが以下var isKeyword = (function () {isKeyword("for").toString()の実行
var keywords = [
"function", "if", "for", "while" ⁄⁄ 以下略
];
var str = "";
for (var i = 0; i < keywords.length; i++) {
if (str.length > 0) str += "|";
str += "ˆ" + keywords[i] + "$";
}
var re = new RegExp(str);
return function (word) {
if (re.exec(word)) return true;
return false;
};
})();
isKeyword("foo").toString()の実行