なぜクロージャ(Closure)と言うのか?

  • 447
    Like
  • 8
    Comment
More than 1 year has passed since last update.

クロージャはわかりづらい。

なんでかと言うと、以下の2つです。

  • 名前
  • 定義がよくわからない

Wikipediaさんなんかで調べると。

クロージャ(クロージャー、英: closure)、関数閉包はプログラミング言語における関数オブジェクトの一種。いくつかの言語ではラムダ式や無名関数で実現している。

関数閉包!!

関数閉包、意味不明すぎる。なんかこの字面が意味分からなくしようとしているような気配すら感じる。(とはいえ、じゃあどんな名前が良いかと言えば、わかりませんし。それに一般的には「クロージャ」で通っていますから、別にいいのですが。)

関数ヘイホウってなに?初めてクロージャを学ぶような僕は、もう、むしろ笑えます。ちなみに、その先の「関数オブジェクトの一種」とか「ラムダ式」なんかも知りません。

けど、JavaScriptのクロージャの事例は、とても分かりやすい。

関数の中に関数があります。

Sample1
function outer() {

    var x = 10;

    function inner() {
        alert(x)
        x = x + 1
    }

    return inner;
}

これに対して、次の記述は以下のようになります。

var f = outer()

f(); // 10
f(); // 11
f(); // 12

この関数の中の関数(ネストされた関数)「『inner』はクロージャです。」

(※普通は、inner部分は無名関数にすることが多いと思いますが、分かりやすさのため、名前有りのネスト関数としておきます。)

もう一度書いてみます。

『inner』はクロージャです。

ポイントは、何かと言うと。

「inner」は、「var x」を操作(キャプチャ)できる。

function inner() {
    alert(x)
    x = x + 1
}

var x = 10;

を操作しているのです。「var x = 10;」は「inner」の外に書いてあるのに。

Closureと呼ばれる所以(ゆえん)。

「inner」は({} の外で定義された)「var x」を操作できる。

これを英語で言うと。

inner closes over x.

(「関数インナー」は「変数x」をクローズオーバーしています。)

ではクローズオーバー(close over)を辞書で調べてみます。

close over
~を囲んで襲い掛かる

(引用元:英辞郎)

なるほど。

「関数インナー」は「変数x」を囲んで襲いかかっている。

(・_・*)

いえ。。
ここで言う「close over」は「take hold」くらいの意味だと思うのです。(もしかして、近寄って覆うという意味かもしれないけど。)つまり、捉えている、手にしているというような意味です。

たしかに、インナーは変数xを、捉えて操作しています。

まとめると。

inner closes over x.

だから、

関数インナーのことを「closure」と呼ぶのだと思うのです。

いろいろ調べて、クロージャの概念は分かってきた気がするのですが。今思うと、閉包でもなかなか良いのではないかと思えて参りました。(._.)

おまけ:Swiftのクロージャ

クロージャは次の3つのタイプのどれかになります。
(日本語にするの難しいので、スーパー適当に書きます。)

  • グローバル関数(普通の関数?)はクロージャです。(ただ、操作できる対象は無い。)
  • ネストされた関数はクロージャです。(上の例はコレ)
  • クロージャ表現は、名前無しクロージャです。

以上、ありがとうございました。

※下記サイトのおかげで僕はクロージャを理解することができました。万謝。
猿でもわかるクロージャ超入門