回答編集履歴

3

コメントを受けて追記

2020/01/15 11:22

投稿

AkitoshiManabe
AkitoshiManabe

スコア5432

test CHANGED
@@ -61,3 +61,71 @@
61
61
 
62
62
 
63
63
  ``let`` が使えるモダンな環境では、使うことも無くなったように思いますが、古いコードを読むためにも知っておくべき内容となります。理解のポイントは**スコープの違い**となります。
64
+
65
+
66
+
67
+ ----
68
+
69
+ コメントを受けて追記)
70
+
71
+ [Wikipedia クロージャ](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3)
72
+
73
+
74
+
75
+ 即時関数は「**関数宣言**+**実行構文**(引数を受け付ける括弧)」で、無名である必要はありません。
76
+
77
+
78
+
79
+ ```
80
+
81
+ // ご質問のコードを named関数 にした例
82
+
83
+ let increment=(function enclosure(){
84
+
85
+ let count=0;
86
+
87
+ return function closure(){
88
+
89
+ count+=1;
90
+
91
+ console.log(count);
92
+
93
+ }
94
+
95
+ })();
96
+
97
+ ```
98
+
99
+
100
+
101
+ 即時関数の実行は enclosureの実行ですので、その返却値(内部で関数宣言されたclosure)が、increment に代入されます(この代入で closure への参照となる)。
102
+
103
+
104
+
105
+ > (この時点で即時関数の役割が消える、let count=0が参照されなくなる)
106
+
107
+
108
+
109
+ 即時関数の役割は、enclosure内で宣言された変数とclosure関数の保持になります(メモリ上には残る)。
110
+
111
+ また、count は、直接参照されなくなりますが、closureを介して間接的に利用はできます。
112
+
113
+
114
+
115
+ > 内側の関数をクロージャにするために return文を使っているのですか?
116
+
117
+
118
+
119
+ increment に closure を参照させ、increment() を実行できるようにするための return です。
120
+
121
+ WikiPediaの説明のように、Javascript では 「関数の中で宣言される関数」はクロージャになりうるものです。
122
+
123
+
124
+
125
+ ちなみに、return を外すと、「Uncaught TypeError: increment is not a function」になりませんか?
126
+
127
+
128
+
129
+ さいごに
130
+
131
+ shiracamus さんの回答にもあるように、「コードを追いかけること」も大事になります。

2

コードの加筆

2020/01/15 11:22

投稿

AkitoshiManabe
AkitoshiManabe

スコア5432

test CHANGED
@@ -15,6 +15,8 @@
15
15
  count+=1;
16
16
 
17
17
  console.log(count);
18
+
19
+ return count;
18
20
 
19
21
  }
20
22
 

1

追記

2020/01/15 09:50

投稿

AkitoshiManabe
AkitoshiManabe

スコア5432

test CHANGED
@@ -6,11 +6,11 @@
6
6
 
7
7
  ```
8
8
 
9
- let count=0;
9
+ var count=0;
10
10
 
11
11
 
12
12
 
13
- let increment=function(){
13
+ var increment=function(){
14
14
 
15
15
  count+=1;
16
16
 
@@ -45,3 +45,17 @@
45
45
  即時関数が実行されるとき(increment宣言時)にcount は初期化され、
46
46
 
47
47
  即時関数のスコープ内で値を保持します。
48
+
49
+
50
+
51
+ ----
52
+
53
+ 追記)
54
+
55
+ クロージャは ``let`` 宣言が登場する以前(簡単に内容を書き換えられてしまう ``var`` しか使えなかった時代)に、如何にして書き換えられないようにするか?といったトリックです。
56
+
57
+ 上記の通り、**スコープを変える**ことで達成しています。
58
+
59
+
60
+
61
+ ``let`` が使えるモダンな環境では、使うことも無くなったように思いますが、古いコードを読むためにも知っておくべき内容となります。理解のポイントは**スコープの違い**となります。