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

回答編集履歴

1

5と6を追記しました。

2017/08/09 10:12

投稿

raccy
raccy

スコア21784

answer CHANGED
@@ -1,5 +1,10 @@
1
1
  `var a = a || {};`というコードは避けるべき書き方、または、意味をなさない書き方です。
2
2
 
3
+ **【注意】**
4
+ `var`がない`a = a || {}`や`window.a = window.a || {}`という書き方や、`||`の左辺が`a`ではない`var a = window.a || {}`という書き方を否定する訳ではありません。
5
+
6
+ この文章はES5以上を想定しており、ES3は一切考慮していません。ES3についてはthink49さんの回答を参考にしてください。
7
+
3
8
  ###varの巻き上げ
4
9
 
5
10
  JavaScriptでは`var`の巻き上げという仕様があります。
@@ -29,6 +34,8 @@
29
34
  2. 関数の引数として使用している。
30
35
  3. クロージャーで外側で定義されている。
31
36
  4. グローバル変数として定義している。
37
+ 5. 他ファイルでグローバル変数として定義している。
38
+ 6. 最初からグローバル変数として定義されている。
32
39
 
33
40
  それぞれ見ていきます。
34
41
 
@@ -166,6 +173,39 @@
166
173
 
167
174
  関数内の`a`がグローバル変数`a`を見に行く事はありません。`var`により関数内の`a`はその関数限定のローカル変数であることを細書し宣言してしまっているからです。グローバル変数がどのように変化しても、関数内の`a`に影響をあてることは無く、それを期待しているのであれば、無意味です。
168
175
 
176
+ ####5. 他ファイルでグローバル変数として定義している。
177
+
178
+ scriptタグで単純に二つのJavaScriptファイルを読み込んだ場合は、グローバル変数が衝突する場合があります。その場合に、既にグローバル変数が定義されていれば、それをそのまま使うというのは有効のように見えます。
179
+
180
+ ```JavaScript
181
+ var a = 1;
182
+ ```
183
+
184
+ ```JavaScript
185
+ var a = a || {};
186
+ // ...
187
+ ```
188
+
189
+ しかし、このようにして衝突を回避するという考え方自体が間違っています。そもそも、グローバル変数が衝突しないように即時関数やモジュールベースの書き方を採用すべきです。
190
+
191
+ ```JavaScript
192
+ (function() {
193
+ var a = a || {};
194
+ // ...
195
+ })();
196
+ ```
197
+
198
+ 即時関数の中に書いてしまえば、意味が無いことは既に述べたとおりです。
199
+
200
+ 全体を即時関数にした場合、ライブラリなのでグローバル変数が定義できないとか思うかもしれませんが、グローバル変数はグローバルオブジェクトのプロパティに過ぎませんので、グローバル変数のプロパティとして定義すれば良いだけです。そのとき、`var`の出番はありませんので、該当のコードが現れる事はありません。
201
+
202
+
203
+ ####6. 最初からグローバル変数として定義されている。
204
+
205
+ Polyfillに使う場合、既にグローバル変数があればオブジェクトを再設定する必要はありませんので、ある意味それは正しいように思えます。
206
+
207
+ しかし、それは完全なPolyfillとはいえません。理由はthink49さんの回答を見てください。また、グローバル変数名衝突回避のためにコード全体を即時関数で囲っているのであれば、`var`の所では必ず再設定になるため、意味がありません。グローバル変数を見たかったら、`var a = window.a || {}`と書く必要があるでしょう。
208
+
169
209
  ###まとめ
170
210
 
171
- よって、私の結論は最初の文に戻ります。`var a = a || {};`というコードは、そもそもコードとして不適切な場所にあるか、無意味な物です。そのため、極めて奇妙なコードに思えます。そのようなコードは良くないサンプルであると判断し、私としては、そのような事が書いてあるサイトや本自体を信頼しません。
211
+ よって、私の結論は最初の文に戻ります。`var a = a || {};`というコードは、そもそもコードとしてどこかが不適切ある(非推奨な方法を取っている)か、無意味な物です。そのため、極めて奇妙なコードに思えます。そのようなコードは良くないサンプルであると判断し、私としては、そのような事が書いてあるサイトや本自体を信頼しません。