回答編集履歴
3
コメントを受けて追記
answer
CHANGED
@@ -29,4 +29,38 @@
|
|
29
29
|
クロージャは ``let`` 宣言が登場する以前(簡単に内容を書き換えられてしまう ``var`` しか使えなかった時代)に、如何にして書き換えられないようにするか?といったトリックです。
|
30
30
|
上記の通り、**スコープを変える**ことで達成しています。
|
31
31
|
|
32
|
-
``let`` が使えるモダンな環境では、使うことも無くなったように思いますが、古いコードを読むためにも知っておくべき内容となります。理解のポイントは**スコープの違い**となります。
|
32
|
+
``let`` が使えるモダンな環境では、使うことも無くなったように思いますが、古いコードを読むためにも知っておくべき内容となります。理解のポイントは**スコープの違い**となります。
|
33
|
+
|
34
|
+
----
|
35
|
+
コメントを受けて追記)
|
36
|
+
[Wikipedia クロージャ](https://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3)
|
37
|
+
|
38
|
+
即時関数は「**関数宣言**+**実行構文**(引数を受け付ける括弧)」で、無名である必要はありません。
|
39
|
+
|
40
|
+
```
|
41
|
+
// ご質問のコードを named関数 にした例
|
42
|
+
let increment=(function enclosure(){
|
43
|
+
let count=0;
|
44
|
+
return function closure(){
|
45
|
+
count+=1;
|
46
|
+
console.log(count);
|
47
|
+
}
|
48
|
+
})();
|
49
|
+
```
|
50
|
+
|
51
|
+
即時関数の実行は enclosureの実行ですので、その返却値(内部で関数宣言されたclosure)が、increment に代入されます(この代入で closure への参照となる)。
|
52
|
+
|
53
|
+
> (この時点で即時関数の役割が消える、let count=0が参照されなくなる)
|
54
|
+
|
55
|
+
即時関数の役割は、enclosure内で宣言された変数とclosure関数の保持になります(メモリ上には残る)。
|
56
|
+
また、count は、直接参照されなくなりますが、closureを介して間接的に利用はできます。
|
57
|
+
|
58
|
+
> 内側の関数をクロージャにするために return文を使っているのですか?
|
59
|
+
|
60
|
+
increment に closure を参照させ、increment() を実行できるようにするための return です。
|
61
|
+
WikiPediaの説明のように、Javascript では 「関数の中で宣言される関数」はクロージャになりうるものです。
|
62
|
+
|
63
|
+
ちなみに、return を外すと、「Uncaught TypeError: increment is not a function」になりませんか?
|
64
|
+
|
65
|
+
さいごに
|
66
|
+
shiracamus さんの回答にもあるように、「コードを追いかけること」も大事になります。
|
2
コードの加筆
answer
CHANGED
@@ -7,6 +7,7 @@
|
|
7
7
|
var increment=function(){
|
8
8
|
count+=1;
|
9
9
|
console.log(count);
|
10
|
+
return count;
|
10
11
|
}
|
11
12
|
```
|
12
13
|
> ①即時関数にするのはなぜか
|
1
追記
answer
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
(「①の回答」に繋がります)
|
3
3
|
|
4
4
|
```
|
5
|
-
|
5
|
+
var count=0;
|
6
6
|
|
7
|
-
|
7
|
+
var increment=function(){
|
8
8
|
count+=1;
|
9
9
|
console.log(count);
|
10
10
|
}
|
@@ -21,4 +21,11 @@
|
|
21
21
|
> ③let count=0で初期化されない(countの値が保持される)のはなぜか
|
22
22
|
|
23
23
|
即時関数が実行されるとき(increment宣言時)にcount は初期化され、
|
24
|
-
即時関数のスコープ内で値を保持します。
|
24
|
+
即時関数のスコープ内で値を保持します。
|
25
|
+
|
26
|
+
----
|
27
|
+
追記)
|
28
|
+
クロージャは ``let`` 宣言が登場する以前(簡単に内容を書き換えられてしまう ``var`` しか使えなかった時代)に、如何にして書き換えられないようにするか?といったトリックです。
|
29
|
+
上記の通り、**スコープを変える**ことで達成しています。
|
30
|
+
|
31
|
+
``let`` が使えるモダンな環境では、使うことも無くなったように思いますが、古いコードを読むためにも知っておくべき内容となります。理解のポイントは**スコープの違い**となります。
|