回答編集履歴

1

`setTimeout` のコールバック関数をネストしない `forLoop3` を追記。ブロックスコープの説明を一文追記。

2019/06/22 02:54

投稿

think49
think49

スコア18162

test CHANGED
@@ -10,13 +10,23 @@
10
10
 
11
11
  - for 文よりも原始的な while 文で再現
12
12
 
13
- - for 文のブロックスコープは関数スコープで再現 ([Lhankor_Mhy さんが指摘されている性質](https://teratail.com/questions/196133#reply-291017))
13
+ - for 文のブロックスコープは関数スコープで再現。関数 `forLoop*` に引数 `i` (= `j`, `k`) が渡されると、**複製された変数 i は関数スコープになる**ので、関数外からの干渉を受けません。 ([Lhankor_Mhy さんが指摘されている性質](https://teratail.com/questions/196133#reply-291017))
14
14
 
15
15
 
16
16
 
17
17
  ```JavaScript
18
18
 
19
19
  'use strict';
20
+
21
+ function handleTimeout (characters, k) {
22
+
23
+ const character = characters[k];
24
+
25
+ console.log(`${character.name}`);
26
+
27
+ }
28
+
29
+
20
30
 
21
31
  function forLoop1 (i) {
22
32
 
@@ -28,17 +38,27 @@
28
38
 
29
39
 
30
40
 
31
- function forLoop2 (i) {
41
+ function forLoop2 (j) {
32
42
 
33
43
  setTimeout(function handleTimeout () { // 分かりやすさ重視で関数をネストさせていますが、毎回、関数を生成するのは無駄なので、基本的には関数を外に追い出す事を推奨します
34
44
 
35
- const character = characters[i];
45
+ const character = characters[j];
36
46
 
37
47
  console.log(`${character.name}`);
38
48
 
39
49
  }, 100);
40
50
 
41
51
  }
52
+
53
+
54
+
55
+ function forLoop3 (k) { // 関数 handleTimeout を外に追い出した場合
56
+
57
+ setTimeout(handleTimeout, 100, characters, k);
58
+
59
+ }
60
+
61
+
42
62
 
43
63
 
44
64
 
@@ -78,11 +98,23 @@
78
98
 
79
99
  }
80
100
 
101
+
102
+
103
+ let k = 0;
104
+
105
+ while (k < characters.length) {
106
+
107
+ forLoop3(k); // "田中" -> "佐藤" -> "久保" -> "飯田"
108
+
109
+ k++;
110
+
111
+ }
112
+
81
113
  ```
82
114
 
83
115
 
84
116
 
85
- BabelのES5コンパイルも似たようなコードを生成していた記憶があります。
117
+ BabelのES5コンパイルも似たようなコードを生成していた記憶があります。
86
118
 
87
119
 
88
120
 
@@ -90,4 +122,12 @@
90
122
 
91
123
 
92
124
 
125
+ ### 更新履歴
126
+
127
+
128
+
129
+ - 2019-06-22 11:54:16 `setTimeout` のコールバック関数をネストしない `forLoop3` を追記。ブロックスコープの説明を一文追記。
130
+
131
+
132
+
93
133
  Re: Sano さん