クロージャ再考

# はじめに
中級以上のJavaScriptプログラマを目指す上で、避けては通れない壁の一つは **クロージャ（Closure）** だと思います。「関数の外側で定義された変数を持つ関数の実行時オブジェクトです」とさらっと説明されることが多いですが、シンプルなだけに理解したつもりになって実は使いどころが分からないってことになりがちです。きちんと自分のものにするには基本から丁寧に理解しないとダメですねってことで、今回はクロージャについてその背景から調べてみたいと思います。

# 歴史と語源
まずは歴史から振り返ってみたいと思います。[Wikipediaによるクロージャの解説](https://en.wikipedia.org/wiki/Closure_(computer_programming))では、以下のような説明があります。

>クロージャの概念は、1960年代にラムダ計算の機械的な実行モデルを構築するために生み出され、1970年に **静的スコープ** と **第一級関数** をサポートするPALプログラミング言語で最初に実装された。1964年、Peter LandinはSECDマシンにおいて **環境とコードのペア** として **クロージャ** を定義した。Joel Mosesは **自由変数** を持つ **開いたラムダ式** がその静的なスコープによって閉じられ（束縛され）、 **閉じたラムダ式** となると言う意味において、Landinによりクロージャという用語が導入されたとしている。この用語は、1975年にSussmanとSteeleが発表したScheme（静的スコープを持つLispの一種）においても引き続いて採用され、その後より広く知られるようになった。

どうやら、1960年代には早くもクロージャという概念が発生したようです。Schemeに至る経緯は、[Java Puzzlers](http://www.amazon.co.jp/Java-Puzzlers-%E7%BD%A0%E3%80%81%E8%90%BD%E3%81%A8%E3%81%97%E7%A9%B4%E3%80%81%E3%82%B3%E3%83%BC%E3%83%8A%E3%83%BC%E3%82%B1%E3%83%BC%E3%82%B9-%E3%82%B8%E3%83%A7%E3%82%B7%E3%83%A5%E3%82%A2%E3%83%BB%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF/dp/4894716895)の著者であるNeal Gafterさんが、[クロージャの歴史](http://gafter.blogspot.jp/2007/01/definition-of-closures.html)で以下のように触れています。

>1950年代終わり、John McCarthyはLispを発表した。その特徴の一つは、lambdaで表記される値としての関数である。lambdaはラムダ計算を由来とする。Lispは **ダイナミックスコープ** を持つ言語である。ダイナミックスコープを持つ言語では、変数参照が評価されると、実行環境は **コールスタック** 上その変数が定義されたスコープまでさかのぼって探索することにより解決される。

>ダイナミックスコープはインタープリタや実装が容易であったが、**FUNARG問題** と呼ばれる問題がすぐに明らかとなった。

>数々のLispの方言が生まれたが、それら全てはダイナミックスコープを持つ言語であった。そんな中、Guy SteeleとGerald Jay Sussmanは簡潔なLisp方言であるSchemeを発表した。

>Schemeはラムダ計算同様に **レキシカルスコープ** を持つ言語である。変数は、その変数を参照するラムダ式が評価される時点でアクティブな静的に取り囲む変数定義に対して束縛される。実装面から言えば、ラムダ式の評価はクロージャを生成する。クロージャとは、ラムダ式内で参照されるがその外側で定義されたすべての変数に対する束縛を保持するオブジェクトとして表現される。このような変数を **自由変数** と言う。クロージャもしくは関数が引数に対して適用（呼び出される）と、クロージャ内の変数束縛はコードに現れる自由変数に意味を与えるために使用される。クロージャという用語は、単に抽象的な言語要素だけではなく実装をも表現しているのである。

以上から、クロージャについて次のようなことが分かります。

* **もともとは関数型言語のコミュニティから発生した** 
関数型言語から発生した概念というのはクロージャ以外にもたくさんあります。Javaの1.8で導入されたラムダも、上でも触れられているラムダ計算[^d]を由来としていますし、Javaで有名になったガベージコレクションも最初に実装されたのはLisp（[Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%83%99%E3%83%BC%E3%82%B8%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)）です。このような技術や概念を勉強するには、関数型言語について勉強してみるのが近道なのかもしれません。
* **開いた（Open）な関数（ラムダ式）が閉じた（Closed）関数（ラムダ式）となることに由来する**　開いたものが閉じるというところからクロージャ（Closure）と言うようです。日本語では閉包と呼ぶらしいです。
* **レキシカルスコープと第一級関数をサポートする言語の実行時のオブジェクトである** JavaScriptもこの条件を満たす言語です。クロージャとは主に実装面の要請から生まれたようですね。上記の解説では、SECDマシンでは環境とコードのペア[^c]、Shcemeでは自由変数を保持する関数オブジェクト（実体）とありますね。

では、開いた関数やレキシカルスコープなど、クロージャを理解する上で必要となるこれらの概念についてみていきたいと思います。

# 閉じた関数と開いた関数

## 閉じた関数
関数内部で参照する変数が引数とローカル変数のみの関数のことを **閉じた関数（Closed functions）** と呼びます。以下のJavaScriptのコードは閉じた関数の例です。

```js:閉じた関数例
function id(x) {
	return x;
}
function sum(x, y) {
	return x + y;
}
function factorial(n) {
	var result = 1; //ローカル変数
	for (i = 1; i <= n; i++) {
		result = result * i;
	}
	return result;
}
```
関数の引数やローカル変数として宣言されている変数を **束縛変数（Bound variable）** と呼びます。束縛変数は関数内部でしか使用されないため、そのすべての出現箇所の名前を変えても関数の意味は変わりません。例えば、上記の```id```関数について、引数```x```の名前を```y```に変えた次の関数は元の関数と等価です。

```js
function id(y) { 
	return y; 
}
```

## 開いた関数

関数の外側で宣言された束縛変数以外の変数を **自由変数（Free variable）** と呼びます。 **開いた関数（Open functions）** とは、自由変数を参照する関数です。次のコードは開いた関数の例です。

```js:開いた関数例
function equalsSome(x) {
	return x === some; //someは自由変数
}
function increment() {
	count++; //countは自由変数
}
```
自由変数は束縛変数のように勝手に名前を変更することはできません。

開いた関数は、その自由変数が定義されていないコンテキストで実行するとエラーとなります。

```js
function increment() {
	count++;
}

increment(); //Error!
console.log(count);
```
一方、自由変数と同じ名前の変数が定義されている環境であれば、関数呼び出しは成功します。

```js
var count = 0; //自由変数の定義
function increment() {
	count++;
}

increment();
console.log(count); // OK. 1を出力
```
このように、開いた関数を実行するにはその関数が参照する自由変数の値を取得する必要があります。つまり、開いた関数を実行するには、関数が参照するすべての自由変数の名前とその値へのマッピング情報が実行時に必要ということになります。このようなマッピング情報（変数と値のペアの集合）を **環境** と呼ぶことがあります。

開いた関数が環境から自由変数の値を取り込むことで閉じた関数となるというところがクロージャを理解する上でのキーとなります。

# 第一級関数と高階関数

## 第一級関数
数値や文字列値などの **値** は、変数に代入したり、関数の引数や戻り値とすることができます。 **第一級関数（first-class functions）** とは、このような通常の値と同じように、関数を値として操作できる性質、もしくはそのような値としての関数のことです。Javaは第一級関数をサポートしません [^a]。Cは関数ポインタを値のように扱えるので同じような性質を持ちますが、普通は第一級関数をサポートするとはみなされません。

JavaScriptの関数はすべて、第一級関数です。したがって、下のように関数リテラルを変数に代入できます。

```js
//関数リテラルを変数に代入
var sum = function (x, y) {
	return x+y;
}

sum(1,2); // 結果は3
```
また、次のように、関数の引数として関数リテラルを渡したり、関数の戻り値として関数リテラルを返すこともできます。

```js
//引数で受け取った関数を２回適用する関数
function twice(f, n) {
	return f(f(n));
}
//値の平方を求める関数
var square = function(n) {
	return n * n;
}
//関数を引数として渡す
twice(square, 2); //結果は16

//自分自身を返す関数
function returnSelf(n) {
	console.log(n);
	return returnSelf;
}
returnSelf(1)(2)(3); //123と出力される
```

## 高階関数
上記の```twice```や```returnSelf```は **高階関数（higher-order function）** と呼ばれます。高階関数とは以下のいずれかの性質を持つ関数のことを指します。

* 引数として関数を受け取る
* 戻り値として関数を返す

高階関数を使うと、コードを圧縮して宣言的にプログラミングすることができるようになります。例えば、JavaScriptのArrayオブジェクトは```filter```メソッドを持っています。filterメソッドは指定されたフィルタ関数（述語）に一致する要素のみをフィルタリングする高階関数です。以下のコードはfilterメソッドにより偶数のみの要素や奇数のみの要素を抽出するコード例です。

```js
//evensは偶数のみの要素配列[2,4,6,8,10]となる
var evens = [1,2,3,4,5,6,7,8,9,10].filter(function (element) {
	return (element % 2 === 0);
});

//oddsは奇数のみの要素配列[1,3,5,7,9]となる
var odds = [1,2,3,4,5,6,7,8,9,10].filter(function (element) {
	return (element % 2 === 1);
});
```
高階関数であるfilterメソッドが、配列のループ処理、フィルタ処理、要素の抽出といった制御処理を内部的に行ってくれるため、ユーザはフィルタ関数だけを取り替えることで、多様な処理を実現することが可能になります。

# ネストした関数とブロック構造

## ネストした関数

ある関数が別の関数の内側で宣言されているとき、この関数を **ネストした関数（nested function）** と呼びます。ネストした関数は **ローカル関数（local function）** とも呼ばれます。JavaやCはネストした関数を利用できません。一方、JavaScriptはネストした関数をサポートしています。

次のコードはJavaScriptでのネストした関数の例です。

```js
//配列から指定の値に等しい要素のみを抽出する関数
function filterEqual(array, n) {
	//ネストした関数
	function isEqual(element) {
		return element === n;
	}
	
	return array.filter(isEqual);	
}

filterEqual([1,2,3,4,2,5,2], 2); //結果は[2,2,2]
```
ネストした関数は、それを囲む関数の外側からはアクセスできないため、グローバルな名前空間を汚さないというメリットがあります。

ネストした関数のもう一つ重要な性質として、外側の関数のローカル変数に自由にアクセスできるという点があります。例えば、上記のコード例のネストした関数である```isEqual```は、外側の関数```filterEquals```の引数```n```を直接参照しています。

## ブロック構造

ネストした関数をサポートする言語は、 **ブロック構造** を持つ言語でもあります。ブロックとは、一連の変数宣言や文のグループです。JavaScirptでは、```{```と```}```で囲まれた部分が一つのブロックとなります。関数の他に、if文やwhile文がブロックを持ちます。ブロックはいくつでもネストすることができ、階層構造を持つプログラムを構成できます。（ただし、JavaScriptでは、関数は関数ブロックの内部でのみしか宣言できません）

# レキシカルスコープとダイナミックスコープ

## レキシカルスコープ
ブロック構造を持つプログラミング言語では、ブロック内で宣言された変数は通常そのブロック内部でのみ参照可能です。このような、変数の有効範囲（変数が参照できる範囲）を **スコープ** と呼びます。JavaScriptでは、 関数の外で宣言された変数はプログラムのどこからでも参照可能な **グローバルスコープ** を持ち、関数ブロック内部で宣言された変数はその関数内でのみ有効な **関数スコープ** となります[^g]。

通常はブロックが入れ子になっている場合、外側のブロックで宣言された変数は内側のブロックでも参照可能です。これは、JavaScriptにおいても同じで、下のようにネストした関数から外側の関数（スコープ）の変数を参照することができます。

```js
function outer() {
  var x = "outer"; //outer関数のローカル変数
  
  function inner() {
    console.log(x); //外側の関数outerのローカル変数xを参照できる
  }
  
  inner();
}

outer(); // "outer"が出力される
```

さて、関数```inner```にとって```x```は自由変数でが、関数```inner```は```outer```の内側で宣言されているため、```inner```が参照する変数```x```は```outer```のローカル変数であることは関数宣言をみればすぐに分かります。このように、関数が宣言された場所のスコープから自由変数が静的に決まるとき、このようなスコープ方式を **レキシカルスコープ（lexical scope）** もしくは **静的スコープ（static scope）** と呼びます。

## ダイナミックスコープ
JavaScriptのプログラマにとってレキシカルスコープは当然のように思えますが、 **ダイナミックスコープ（dynamic scope）** と呼ばれるスコープ方式をサポートする言語もあります。ダイナミックスコープの下では、自由変数は関数の宣言時に決まるのではなく、関数の呼び出し時のスコープから動的に決まります。

以下のコードを見てください。```inner```は自由変数```x```を持ちます。```dynamic```は変数```x```を宣言したのち、```inner```関数を呼び出します。レキシカルスコープを持つJavaScriptでは、```dymamic```が宣言する変数```x```は、```inner```が参照する```x```とは別のスコープとなるため、```dynamic```関数内での変数```x```の宣言は```inner```の実行に影響しません。一方、もし、JavaScriptがダイナミックスコープを持つと仮定するなら、```dynamic```関数内部で```inner```が実行されると、```inner```が参照する自由変数```x```は```dynamic```のローカル変数となります。

```js
function outer() {
  var x = "outer";
  
  function inner() {
    // xは自由変数
    console.log(x);
  }

  function dynamic() {
    // 変数xを宣言して、自由変数xを持つinner関数を呼び出す
    // ダイナミックスコープの場合、innerが内部で参照するxは、この変数に実行時解決される。
    var x = "dynamic";
    inner();
  }
  
  dynamic();
}

outer(); // もしJavaScriptがダイナミックスコープをサポートするなら、"dynamic"が出力されるはず。（実際は"outer"と出力される）
```
ダイナミックスコープは実装が容易（変数の解決はコールスタックを辿ればよい）という利点があり、もともとLispなどで採用されていたようです。ただし、実行時の構造に依存するためバグを生みやすいという点や、レキシカルスコープはより強力なクロージャを利用できるという点などから、現在の代表的な言語はほぼレキシカルスコープを採用しています。



# アクティベーションレコードとFUNARG問題

## アクティベーションレコード

C言語のような内部関数や高階関数をサポートしない言語では、関数の実行時に **アクティベーションレコード** と呼ばれる一時領域が生成されます。アクティベーションレコードは、 **スタックフレーム** とも呼ばれ、関数のローカル変数や関数終了時の戻り先を保持する記憶領域です。関数の呼び出し毎にアクティベーションレコードが生成されて **コールスタック** と呼ばれるスタック領域にpushされます。関数が終了するとコールスタックからアクティベーションレコードがpopされて呼び出し元の関数数の実行が再開されます。

この実行モデルをJavaScriptのプログラムを例にとって説明してみましょう。以下のサンプルコードを見てください。関数```foo```はローカル変数```x```（引数）と```y```を持ち、関数```bar```を内部的に呼び出しています。関数```bar```はローカル変数```x```（引数）と```z```を持っています。


```js
function foo(x) {
	var y = 10; // (a)
	bar(x + y); // (b)
	console.log('foo finished'); //(c)
}

function bar(x) {
	var z = 50;
	console.log(x + z); //(d)
}

foo(10); //(x)
```

さて、(x)の地点において、```foo```が呼び出される前のコールスタックは空です。ここで、```foo```が引数```10```で呼び出され、地点(a)に来たとき、コールスタックは次のようになります。ここで、```f:{a:1,b:2}```は、関数```f```のアクティベーションレコードを表し、値が```1```のローカル変数```a```と値が```2```のローカル変数```b```を記憶領域として持っているものとします。

|コールスタック|
|------------|
|foo: {x:10, y:10}|

次に、(b)の地点で関数```bar```が引数```20(=x+y)```呼びだされると、コールスタックは```bar```のアクティベーションレコードがpushされて以下のようになります。地点(d)で```console.log```関数が参照する変数```x```と```z```の値は、```bar```自身のアクティベーションレコードから取得できます。

|コールスタック|
|------------|
|bar: {x:20, z:50}|
|foo: {x:10, y:10}|

最後に、関数```bar```の実行が終わり、(c)の地点に到達すると、```bar```のアクティベーションレコードはpopされてコールスタックは```foo```のアクティベーションレコードのみが残ります。

|コールスタック|
|------------|
|foo: {x:10, y:10}|

最後に、```foo```の実行も終了するとコールスタックは再度空となります。
## FUNARG問題

レキシカルスコープや高階関数をサポートするJavaScriptのような言語では、上記の実行モデルでは解決できない問題が発生します。このような問題を一般的に **FUNARG問題**と呼びます。JavaScriptのコードを用いて、FUNARG問題の具体例を考えてみましょう。

### ケース１
例えば、以下のJavaScriptのコードをみてください。```bar```は```foo```のローカル変数```x```を出力する単純な関数です。

```js
function foo(x) {
	function bar() {
		console.log(x); //(b)
	}
	
	bar(); //(a)
}

foo(10); //10が出力される
```

地点(a)での```bar```の呼び出し前のコールスタックは次のようになるでしょう。（ここで、JavaScriptでは関数も第一級の値であるので、アクティベーションレコードにその関数の実体が保持されます。）


|コールスタック|
|-----------|
|foo: {x:10, bar:barの関数実体}|

さて、```bar```が呼び出されて地点(b)に到達したときのコールスタックは次のようになります。```bar```はローカル変数を持たないため、アクティベーションレコードも空です。

|コールスタック|
|-----------|
|bar: {}|
|foo: {x:10, bar:barの関数実体}|

ここで、```console.log(x)```が実行されたとき、アクティベーションレコードは空であるため、変数```x```の値を取得することができません。

上記のケースでは、```foo```のアクティベーションレコードから変数```x```の値を取得できるのでは？と思われるかもしれませんが、これはダイナミックスコープをサポートする言語において有効な手法です。しかし、レキシカルスコープを採用するJavaScriptでは解決できません。これが、ダイナミックスコープの実装が容易である理由の一つです。（本記事のレキシカルスコープとダイナミックスコープの解説を参照してみてください。）

### ケース２

さらに、以下のようなコードを考えてみましょう。```funarg```関数は内部関数```foo```を持ちます。```foo```は関数```bar```をリターンする高階関数です。```funarg```を実行すると3が出力されます。


```js
function funarg() {
	function foo(x) {
		function bar() {
			console.log(x); //(c)
		}
	
		return bar;
	}

	var f = foo(3); //(a)
	f();//3が出力される //(b)
}

funarg(); //(x)
```

地点(x)で```funarg```を実行すると、コールスタックは以下のようになります。ここで、ローカル変数```f```の値は、```funarg```の実行開始時にはまだ決まらないため```undefined```となります。

|コールスタック|
|-----------|
|funarg: {foo:関数の実体, f:undefined}|

地点(a)で```foo```が引数```3```で実行されたとき、コールスタックに```foo```のアクティベーションレコードがpushされます。

|コールスタック|
|-----------|
|foo: {x:3, bar:bar関数の実体(*1)}|
|funarg: {foo:関数の実体, f:undefined}|

関数```foo```の実行が終わると、```foo```のリターン値であるbar関数の実体(*1)が変数```f```に代入されます。この時点で、コールスタックからは```foo```のアクティベーションレコードはpopされます。

|コールスタック|
|-----------|
|funarg: {foo:関数の実体, f:bar関数の実体(*1)}|

さて、地点(b)において ```f```（bar関数）の実行が開始されると、```bar```のアクティベーションレコードがpushされてコールスタックは次のようになります。

|コールスタック|
|-----------|
|bar: {}|
|funarg: {foo:関数の実体, f:bar関数の実体(*1)}|

さて、ここで```bar```のコードが実行されて、地点(c)に到達したとします。このとき、変数```x```の値はコールスタック上のどこにも存在しません。よって、```bar```を実行することはできません。

# クロージャ

JavaScriptはレキシカルスコープと内部関数（と高階関数）をサポートする言語です。上記でみたように、コールスタックを用いたシンプルな実行モデルではFUNARG問題が発生します。どうやってこの問題を解決できるでしょうか？

次のコードをみてください。関数```bar```は外側の関数```foo```のローカル変数```x```を自由変数として参照する開いた関数です。```bar```のような開いた関数を実行するには、実行時に自由変数の値を取得する方法が必要になります。これを実現するには、```bar```の実行時に、（```x```の値を保持する）```foo```のアクティベーションレコードを参照できればよさそうです。

```js
function foo(x) {
	function bar(y) {
		console.log(x + y); // (z) xは自由変数。
	}
	
	bar(1); // (b) barの実行時、barが参照する自由変数xの値は1 
	bar(2); // (c) barの実行時、barが参照する自由変数xの値は2 
	bar(10); // (d) barの実行時、barが参照する自由変数xの値は10
}

foo(100); // (a) fooを実行。101, 102, 110が出力される。
foo(200); // (e) fooを実行。201, 202, 210が出力される。
```
JavaScriptの実行エンジンは、関数宣言を評価すると、関数自身のコードとその時点でアクティブなアクティベーションレコード（への参照）を保持するオブジェクトを生成します。これが、 **クロージャ** の正体です。関数の実行はクロージャを実行することであり、クロージャが実行されると、その関数自身のローカル変数を保持する自分自身のアクティベーションレコードが生成されるとともに、クロージャが参照するアクティベーションレコードへのリンクが生成されます。このリンクを辿っていくことで自由変数の値を参照できるようになります。

アクティベーションレコードは他のアクティベーションレコードから参照（リンク）される可能性があるため、コールスタックモデルのように関数呼び出しが終了した時点でアクティベーションレコードを削除（pop）することはできません。そのため、アクティベーションレコードはスタックではなく、ヒープなどのデータ領域に生成されます。そして、不要になった時点でGCなどが削除します。（この辺は各実行環境の実装によるようですが、以下の説明ではヒープとします。）

## 実行モデル

以下では、```f:{x:1, y:2, _scope_:n}```を関数```f```のアクティベーションレコード（```x```と```y```は```f```のローカル変数とその値）とします。ここで、```_scope_```はアドレス```n```で参照される別のアクティベーションレコードを表します。また、```Closure(f, n)```は関数```f```とアドレス```n```で参照されるアクティベーションレコードから成るクロージャとします。

さて、上記のサンプルコードに戻りましょう。地点(a)で```foo(100)```が実行されると、JavaScriptの実行エンジンは以下のような動作を行います。

1. ローカル変数```x```の値を100で初期化したアクティベーションレコード```foo{x:100, bar:undefined}```をヒープに生成する。
  

|アドレス|ヒープ|
|---|-----------|
|ref(1)|foo:{x:100, bar:undefined}|
　
2. ```bar```の関数宣言を評価し、```bar```と1.で生成した```foo```のアクティベーションレコードから成るクロージャ```Closure(bar, ref(1))```を生成する。この時点で、ヒープ領域は次のようになる。

|アドレス|ヒープ|
|---|-----------|
|ref(1)|foo:{x:100, bar:Closure(bar, ref(1))}|
　
3. 地点(b)において、2.で生成したクロージャ```Closure(bar, ref(1))```を引数```１```で呼び出す。このとき、```bar```のアクティベーションレコード```bar{y:1, _scope_:ref(1)}```が生成される。ここで、```_scope_```にはクロージャの参照アドレスが設定されることに注目。

|アドレス|ヒープ|
|---|-----------|
|ref(2)|bar:{y:1, \_scope_:ref(1)}|
|ref(1)|foo:{x:100, bar:Closure(bar, ref(1))}|
　
4. ```bar```の実行を開始する。
5. 地点(z)において、```console.log(x+y)```を実行する。
ここで、変数```y```の値はref(2)で表される自身のアクティベーションレコードから取得できる。自由変数```x```の値は、_scope_を辿ることで```foo```のアクティベーションレコードから取得できる。
6. 地点(c)において、```bar(2)```の実行を開始する。(1.で生成したクロージャ```Closure(bar, ref(1))```を引数2で呼び出す)。3〜5を繰り返す。地点(z)におけるヒープの状態は次のようになる。

|アドレス|ヒープ|
|---|-----------|
|ref(3)|bar:{y:2, \_scope_:ref(1)}|
|ref(1)|foo:{x:100, bar:Closure(bar, ref(1))}|
　
7. 地点(d)において、```bar(10)```の実行を開始する。(1.で生成したクロージャ```Closure(bar, ref(1))```を引数10で呼び出す)。3〜5を繰り返す。地点(z)におけるヒープの状態は次のようになる。

|アドレス|ヒープ|
|---|-----------|
|ref(4)|bar:{y:100, \_scope_:ref(1)}|
|ref(1)|foo:{x:100, bar:Closure(bar, ref(1))}|

ここで、```foo```の呼び出しごとに、```foo```の異なるアクティベーションレコードが生成されることに注意してください。つまり、```foo(100)```と```foo(200)```の呼び出しごとにその内部の```bar```関数が参照する自由変数```x```の実体も異なります。

## 自由変数の共有

もう一つ重要な点は、JavaScriptでは、クロージャが参照する自由変数は値のコピーではなく変数そのものであることです。これにより、変数の値を書き換えることが可能であり、同じ関数内部のクロージャは同一の変数を変数を共有できます。次のコードでは、ネストした関数```bar```と```update```は同一の変数```x```を参照しています。```update```関数のように、自由変数```x```の値を更新できることが分かります。

```js
function foo(x) {
	function bar() {
		console.log(x);
	}
	
	function update(y) {
		x = y;
	}
	
	bar(); //100が出力される
	update(10);
	bar(); //10が出力される
}

foo(100);
```

## 関数より長生きするローカル変数

関数を返す高階関数とレキシカルスコープを組み合わせると、さらに面白いことが実現できます。次の関数をみてください。この関数は、引数として２つの関数```f```および```g```を受け取り、```f```と```g```を合成した関数を返す高階関数です。すなわち、```compose(f,g)(x)```は```f(g(x))```と等価です。

```js
function compose(f, g) {
  return function(x) {
  	//fとgは自由変数
    return f(g(x));
  };
}

function squre(x) {
	return x * x;
}

var f = compose(squre, squre); // (a)
f(2); //結果は16
```

上記のコードにおいて、関数```compose```はネストした無名関数を返します。この無名関数は２つの自由変数```f```と```g```を参照します。これらの自由変数は```compose```関数のローカル変数（引数）です。地点(a)において、```compose```を実行すると、無名関数のクロージャが生成されて返されます。このクロージャは```compose```のアクティベーションレコード（ローカル変数```f```と```g```を持つ）を保持します。これにより、```compose```の実行が終了した後でも、クロージャは変数```f```と```g```を参照することができます。つまり、```compose```関数の実行が終了したにもかかわらず、そのローカル変数```f```と```g```は生き続けます。


ネストした関数のセクションで用いたサンプルコードの```twice```関数は、```compose```関数を使うと次のように定義できます。

```js
//引数の関数を2回適用する関数
var twice = function(f, x) {
  return compose(f, f)(x);
};

//引数にプラス1する関数
var plus1 = function(x) {
  return x + 1;
};

console.log(twice(plus1, 1)); //結果は3
console.log(twice(plus1, 2)); //結果は4
```

また、配列の要素のうち、偶数の要素数をカウントする関数は次のように記述できます。

```js
//配列の偶数の要素数をカウントする関数
var countEven = function(array) {  
  function even(array) {
    return array.filter(function (e) {
      return (e % 2 === 0);
    });
  }
  
  function count(array) {
    return array.length;
  }
 
  return compose(count, even)(array);
};

console.log(countEven([1,2,3,4,5])); //結果は2
console.log(countEven([1,2,3,4,5,6,7,8,9])); //結果は4
```

# クロージャの主な使いどころ

## 高階関数の引数として自由変数を持つ関数を渡す
以下のコードを見てください。配列オブジェクトの高階関数```filter```の引数である無名関数は、```x```を自由変数として持ちます。```x```は```filter```関数の外部で宣言された変数です。このように、クロージャを利用することにより、関数（この例では```filter```）の実行時にその外部で宣言された変数を利用できるようになります。[^b]

```js
//配列arrayからxに等しい要素だけを抽出する関数
function filterEquals(array, x) {
	return array.filter(function (element) {
		return element === x;
	});
}

var filtered = filterEquals([1,2,3,4,2], 2); //結果は[2,2]
```


## 状態を持つオブジェクトの生成
クロージャは自由変数（データ）と関数（コード）を持ったオブジェクトとみなすことで、オブジェクト指向言語におけるオブジェクトを実現することができます。以下のコードはクロージャの例としてお馴染みのカウンターですが、```makeCounter```関数により```count```変数をデータとして持つカウンタオブジェクトを生成しています。

```js
function makeCounter() {
	var count = 0;
	return function() {
		return count++;
	};
}

var counter = makeCounter();
counter();
counter();
console.log(counter()); //2が出力される
```

以下のように、複数の関数（メソッド）もつオブジェクトも実現できます。

```js
function makeCounter() {
	var count = 0;
	return {
		increment: function() {
			count++;
		},
		decrement: function() {
			count--;
		},
		val: function() {
			return count;
		}
	};
}

var counter = makeCounter();

counter.increment();
counter.increment();
console.log(counter.val()); //2が出力される
counter.decrement();
console.log(counter.val()); //1が出力される
```

## モジュールパターン

クロージャを利用することにより、プログラムをモジュール単位に構造化し、各モジュールの内部構造を外部から隠蔽することができるようになります。よくあるパターンとして、以下のように即時実行関数を実行することでモジュール（オブジェクト）を生成し、公開する関数のみをモジュールに追加する方法です。


```js
//モジュール
var Module = {};

(function(M) {
	//プライベートなローカル変数
	var localVar = "local";
	//プライベートなローカル関数
	function localFunction() {
		return localVar;
	}
	//パブリックな関数はモジュールに追加
	M.globalFunction = function() {
		console.log(localFunction());
	};
  
})(Module); //即時実行関数にモジュールオブジェクトを渡して実行

//パブリック関数の呼び出し
Module.globalFunction(); //localと出力される
//プライベート関数は呼び出せない
Module.localFunction(); //エラー
```


# 参考サイトと書籍

* https://en.wikipedia.org/wiki/Closure_(computer_programming)
Wikipediaによるクロージャの解説です。

* http://gafter.blogspot.jp/2007/01/definition-of-closures.html
[Java Puzzlers](http://www.amazon.co.jp/Java-Puzzlers-%E7%BD%A0%E3%80%81%E8%90%BD%E3%81%A8%E3%81%97%E7%A9%B4%E3%80%81%E3%82%B3%E3%83%BC%E3%83%8A%E3%83%BC%E3%82%B1%E3%83%BC%E3%82%B9-%E3%82%B8%E3%83%A7%E3%82%B7%E3%83%A5%E3%82%A2%E3%83%BB%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF/dp/4894716895)の著者の一人であるNeal Gafterによる、クロージャの歴史です。下のMartin Flowerの記事も参照しています。

* http://martinfowler.com/bliki/Lambda.html
Martin Flowerによる動的言語（Ruby）のラムダの解説。クロージャについても触れられています。

* http://dmitrysoshnikov.com/ecmascript/chapter-6-closures/
ECMAScriptのクロージャ仕様に関する解説記事です。実装面が詳しいです。

* [JavaScriptパターン ―優れたアプリケーションのための作法](http://www.amazon.co.jp/JavaScript%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-%E2%80%95%E5%84%AA%E3%82%8C%E3%81%9F%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E4%BD%9C%E6%B3%95-Stoyan-Stefanov/dp/4873114888)
モジュールパターンを含む、クロージャを利用したいろいろなパターンが紹介されています。

* [Scalaスケーラブルプログラミング](http://www.amazon.co.jp/Scala%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%A9%E3%83%96%E3%83%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E7%AC%AC2%E7%89%88-Martin-Odersky/dp/4844330845)
クロージャについて、開いた関数と閉じた関数についての解説もあります。

* [LET OVER LAMBDA Edition 1.0](http://www.amazon.co.jp/LET-OVER-LAMBDA-Edition-1-0/dp/4434133632)
レキシカルスコープとクロージャの部分だけ少しかじりました。

---

[^d]: アロンゾ・チャーチによって考案された計算モデルです。（[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%A0%E3%83%80%E8%A8%88%E7%AE%97)）
[^a]: ラムダはオブジェクトであって関数ではありません。
[^c]: Sはスタック、Eは環境、Cはコード、Dはダンプを表すようです。（[Wikipedia](https://ja.wikipedia.org/wiki/SECD%E3%83%9E%E3%82%B7%E3%83%B3)）
[^b]: クロージャを持たないC言語では、ポインタを利用して関数宣言の外部の変数値を受け渡すことができます。
[^e]: 実際には関数```bar```自体もアクティベーションレコードに登録されます。```bar```が評価されると、この値がクロージャとなります。
[^g]: ECMAScript 6では```let```によるブロックスコープが導入されています。([MDNによる解説記事](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let))