teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

変数の巻き上げ

2019/08/14 09:39

投稿

think49
think49

スコア18194

answer CHANGED
@@ -58,4 +58,54 @@
58
58
  - HTML上で同じID(id="plus")を複数回記述する事は出来ません(文法違反)
59
59
  - CSSのIDセレクタは初めに出現した要素のみに適用される仕様です
60
60
 
61
+ ### 変数の巻き上げ(Variable hoisting)
62
+
63
+ JavaScript では変数の「初期化」と「代入」は分けて実行されます。
64
+
65
+ - 変数は**関数呼び出し時**に生成されます
66
+ - 関数呼び出し直後に、関数内で宣言された**全ての変数を undefined で初期化+*します
67
+ - `var a = 1;` が実行された時、1 が**代入**されます(初期化は既に完了しています)
68
+
69
+
70
+ ```JavaSctipt
71
+ function sample1 () { // 変数 a が undefined で「初期化」される
72
+ console.log(a); // undefined
73
+
74
+ var a = 1; // 1 が「代入」される
75
+ }
76
+
77
+ sample1();
78
+ ```
79
+
80
+ この挙動は分かりづらい為、あえて初期化と代入を分けてコートを書く事を好む人もいます。
81
+
82
+ ```JavaSctipt
83
+ function sample2 () { // 変数 a が undefined で「初期化」される
84
+ var a; // 初期化済なので何もしないが、このコードはundefined で初期化を意図している為、分かりやすい
85
+
86
+ console.log(a); // undefined
87
+ a = 1; // 1 が「代入」される
88
+ }
89
+
90
+ sample2();
91
+ ```
92
+
93
+ for 文の挙動は下記になります。
94
+
95
+ ```JavaSctipt
96
+ function sample3 () { // 変数 elememts,i,len が undefined で「初期化」される
97
+
98
+ var elememts = document.querySelectorAll('.plus'); // NodeListが「代入」される(3つの要素を持つとする)
99
+
100
+ for (var i = 0, len = elememts.length; i < len; i++) { // i, len が代入される(3回繰り返し)
101
+ elements.addEventListener('click', () => console.log(i), false); // clickリスナー実行時にはループ処理が終わっている為、i 値は常に3となる
102
+ }
103
+ }
104
+
105
+ sample3();
106
+ ```
107
+
108
+ ところで、`let`, `const` でも巻き上げは発生しています。
109
+ ただし、変数定義文より前に変数参照が行われると、`ReferenceError` で停止する為、事実上、巻き上げを考慮する必要がなくなっています。
110
+
61
111
  Re: YESYUKI17 さん

1

ECMAScript 6 compatibility table

2019/08/14 09:39

投稿

think49
think49

スコア18194

answer CHANGED
@@ -5,6 +5,7 @@
5
5
  下記に疑似コードを書きました。
6
6
 
7
7
  - [for + let - JSFiddle](https://jsfiddle.net/7gyn2kpa/)
8
+ - [for/for-in loop iteration scope - ECMAScript 6 compatibility table](http://kangax.github.io/compat-table/es6/#test-let_for/for-in_loop_iteration_scope)
8
9
 
9
10
  ```HTML
10
11
  <h2>let + var (type1) ※IE11は未対応</h2>