回答編集履歴

2

関数宣言と関数式、 グローバルコード上の this 値

2018/05/06 16:31

投稿

think49
think49

スコア18166

test CHANGED
@@ -158,4 +158,116 @@
158
158
 
159
159
 
160
160
 
161
+ ### 関数宣言と関数式
162
+
163
+
164
+
165
+ > function(){ ... } はラムダ式の定義、
166
+
167
+
168
+
169
+ 式の定義という意味では正しいのですが、実は条件があります。
170
+
171
+
172
+
173
+ | 関数の種類 | 制限事項 |
174
+
175
+ | ------------------------------ | ------------------------------------------------------------ |
176
+
177
+ | 関数宣言 (FunctionDeclaration) | function キーワードで始まらなければならず、名前をつけなければならない |
178
+
179
+ | 関数式 (FunctionExpression) | function キーワードで始まってはならず、名前は付けても付けなくても良い |
180
+
181
+
182
+
183
+ 関数宣言は**function キーワードで始まらなければならない**と決まっている為、いわゆる即時関数と呼ばれる書き方では `()` や `+` 等を先頭に置くことで関数式化しています。
184
+
185
+
186
+
187
+ ```JavaScript
188
+
189
+ (function main () { // "(" で始める事で関数式扱いとなる (関数式なので名前は付けても良い)
190
+
191
+ console.log(main.name);
192
+
193
+ }());
194
+
195
+ ```
196
+
197
+
198
+
199
+ ### グローバルコード上の this 値
200
+
201
+
202
+
203
+ > thisはDOMツリーのルートということなのですね。
204
+
205
+
206
+
207
+ これは違います。
208
+
209
+ DOM 規定ではなく、ECMAScript 規定によって、「**グローバルコード上では this 値がグローバルオブジェクトである**」と定められています。
210
+
211
+ そして、`window` キーワードでグローバルオブジェクトを参照できるのは、DOM 規定によるものです。
212
+
213
+
214
+
215
+ ```JavaScript
216
+
217
+ /**
218
+
219
+ * グローバルコード
220
+
221
+ */
222
+
223
+ window.parseFloat('1.0'); // (A)
224
+
225
+ this.parseFloat('1.0'); // (B)
226
+
227
+ ```
228
+
229
+
230
+
231
+ 上記コードは、Webブラウザ上ではどちらも期待通りに動作しますが、Node.js では (A) が動作せず、(B) のみ期待通りに動作するでしょう。
232
+
233
+ Node.js は window キーワードでグローバルオブジェクトを参照できませんが、ECMAScript 仕様は実装されています。
234
+
235
+ その為、ECMAScript 仕様の範囲内である `this` 値による参照は有効なのです。
236
+
237
+
238
+
239
+ ---
240
+
241
+
242
+
243
+ ちなみに、DOM 上のルートノードは元々は `document` でした。
244
+
245
+ Document Object Model の名が示す通りですね。
246
+
247
+ ですので、`document.parentNode` は未定義です。
248
+
249
+
250
+
251
+ `window` は長らく、標準化されていませんでしたが、HTML Standard の既定と同時に `window` オブジェクトが定義され、DOM Standard でも定義されました。
252
+
253
+
254
+
255
+ - [HTML Standard — Window object, WindowProxy exotic object(日本語訳)](https://triple-underscore.github.io/HTML-window-ja.html#the-window-object)
256
+
257
+ - [4.2. Node tree - DOM Standard](https://dom.spec.whatwg.org/#node-trees)
258
+
259
+
260
+
261
+ DOM Standard では少し、複雑で3つのツリーが出てきます。
262
+
263
+
264
+
265
+ - Node tree上 に Document は存在しますが、Window は存在しません
266
+
267
+ - Document tree 上の root は document です
268
+
269
+ - Shadow tree 上の root は ShadowRoot であり、Window です
270
+
271
+
272
+
161
273
  Re: Chironian さん

1

main() 関数の代替

2018/05/06 16:31

投稿

think49
think49

スコア18166

test CHANGED
@@ -1,3 +1,7 @@
1
+ ### JavaScriptの実行タイミング
2
+
3
+
4
+
1
5
  > これに対してJavaScriptの関数がいつ呼ばれるのか?の把握が甘そうなのです。
2
6
 
3
7
 
@@ -26,4 +30,132 @@
26
30
 
27
31
 
28
32
 
33
+ ### main() 関数の代替
34
+
35
+
36
+
37
+ JavaScriptの場合、関数を自由に定義できるので main 関数という概念はありませんが、ES3, ES5 時代にはグローバル汚染を回避する為に即時関数で括る慣習がありました。
38
+
39
+
40
+
41
+ ```JavaScript
42
+
43
+ <script>
44
+
45
+ /**
46
+
47
+ * (A) ES3/ES5
48
+
49
+ */
50
+
51
+ 'use strict';
52
+
53
+ (function () { // FunctionExpression
54
+
55
+ function handleClick (event) {
56
+
57
+ console.log(event.type);
58
+
59
+ }
60
+
61
+
62
+
63
+ function main () {
64
+
65
+ this.document.addEventListener('click', handleClick, false);
66
+
67
+ }
68
+
69
+
70
+
71
+ main.call(this);
72
+
73
+ }.call(this));
74
+
75
+ </script>
76
+
77
+ ```
78
+
79
+
80
+
81
+ ES6 (ES2015) 時代もグローバル汚染は回避しますが、回避手段が増えています。
82
+
83
+
84
+
85
+ ```JavaScript
86
+
87
+ <script>
88
+
89
+ /**
90
+
91
+ * (B) ES6 (ES2015) type1
92
+
93
+ */
94
+
95
+ 'use strict';
96
+
97
+ (() => { // ArrowFunction
98
+
99
+ function handleClick (event) {
100
+
101
+ console.log(event.type);
102
+
103
+ }
104
+
105
+
106
+
107
+ const main = () => {
108
+
109
+ this.document.addEventListener('click', handleClick, false);
110
+
111
+ };
112
+
113
+
114
+
115
+ main();
116
+
117
+ })();
118
+
119
+
120
+
121
+ /**
122
+
123
+ * (C) ES6 (ES2015) type2
124
+
125
+ */
126
+
127
+ { // BlockStatement
128
+
129
+ const handleClick = function handleClick (event) {
130
+
131
+ console.log(event.type);
132
+
133
+ };
134
+
135
+
136
+
137
+ const main = () => {
138
+
139
+ this.document.addEventListener('click', handleClick, false);
140
+
141
+ };
142
+
143
+
144
+
145
+ main();
146
+
147
+ }
148
+
149
+ </script>
150
+
151
+ ```
152
+
153
+
154
+
155
+ いずれも私が気を付けていることは、**main 関数がグローバルコードと同じ this 値を持っていること**です。
156
+
157
+ が、これは私の個人的なポリシーであり、標準的な基準があるわけではありません。
158
+
159
+
160
+
29
161
  Re: Chironian さん