回答編集履歴

7

テキスト修正

2019/09/16 17:02

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -220,7 +220,7 @@
220
220
 
221
221
 
222
222
 
223
- 上記は、以下の3つ
223
+ 上記のMDNの説明には、以下の3つ
224
224
 
225
225
 
226
226
 

6

テキスト修正

2019/09/16 17:02

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -396,7 +396,7 @@
396
396
 
397
397
  ```
398
398
 
399
- と宣言された関数 `init0` を実行することを考えます。最も簡単には、`init0`を実行するには
399
+ と宣言された関数 `init0` を実行することを考えます。最も簡単に関数`init0`を実行するには
400
400
 
401
401
  ```javascript
402
402
 

5

テキスト修正

2019/09/16 15:33

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -524,7 +524,7 @@
524
524
 
525
525
 
526
526
 
527
- - Qiita: [「開眼!JavaScript」サンプルコード#1/4 第1-4章](https://qiita.com/jun68ykt/items/5aee04682f95f2354398) (※5章以降は、のページからリンクされた別記事です。)
527
+ - Qiita: [「開眼!JavaScript」サンプルコード#1/4 第1-4章](https://qiita.com/jun68ykt/items/5aee04682f95f2354398) (※5章以降は、左記のページからリンクされた別記事です。)
528
528
 
529
529
 
530
530
 

4

テキスト修正

2019/09/16 14:25

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -85,3 +85,567 @@
85
85
  でもよいです。
86
86
 
87
87
  - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/eYOjgjW?editors=0012](https://codepen.io/jun68ykt/pen/eYOjgjW?editors=0012)
88
+
89
+
90
+
91
+
92
+
93
+ ### 追記2
94
+
95
+
96
+
97
+ 質問者さまからのコメントを、以下
98
+
99
+
100
+
101
+ (1) コードについての説明
102
+
103
+
104
+
105
+ > 今回教えていただいた方法について仕組みが今ひとつ理解できません…。
106
+
107
+
108
+
109
+
110
+
111
+ (2) 参考資料、図書について
112
+
113
+
114
+
115
+ > 今回教えていただいた手法をちゃんと理解するのに役立つ参考サイト・文献など
116
+
117
+
118
+
119
+ の2点に分けて、それぞれに回答します。
120
+
121
+
122
+
123
+ #### (1) コードについての説明
124
+
125
+
126
+
127
+ 以下について回答します。
128
+
129
+
130
+
131
+ > 教えていただいたものだとinit0,init1,init2 という文字の配列のように見えます。。。
132
+
133
+ > また、「initializers[str]();」これで関数を実行できるというやり方も今回初めて目にしたのですが
134
+
135
+ こういう方法は何か名前がついていますか? 
136
+
137
+
138
+
139
+
140
+
141
+ まず、
142
+
143
+
144
+
145
+ > 教えていただいたものだとinit0,init1,init2 という文字の配列のように見えます。。。
146
+
147
+
148
+
149
+ についてです。
150
+
151
+ `top.js` に、関数名が `init` で始まる、以下の3つの関数が宣言されています。
152
+
153
+
154
+
155
+ ```javascript
156
+
157
+ function init0() {
158
+
159
+  ・・・
160
+
161
+ }
162
+
163
+
164
+
165
+ function init1() {
166
+
167
+  ・・・
168
+
169
+ }
170
+
171
+
172
+
173
+ function init2() {
174
+
175
+  ・・・
176
+
177
+ }
178
+
179
+ ```
180
+
181
+ これらに対して、先の回答に書いた、`var initializers` に代入している以下のオブジェクトリテラル
182
+
183
+ ```javascript
184
+
185
+ {
186
+
187
+ init0,
188
+
189
+ init1,
190
+
191
+ init2
192
+
193
+ }
194
+
195
+ ```
196
+
197
+ は、以下
198
+
199
+ ```javascript
200
+
201
+ {
202
+
203
+ init0: init0,
204
+
205
+ init1: init1,
206
+
207
+ init2: init2
208
+
209
+ }
210
+
211
+ ```
212
+
213
+ を省略した書き方です。このような省略した書き方ができるようになったのは ECMAScript 2015 からです。
214
+
215
+ MDN では、以下に説明があります。
216
+
217
+
218
+
219
+ - MDN: オブジェクト初期化子 - [ECMAScript 2015 での新しい表記法](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015)
220
+
221
+
222
+
223
+ 上記では、以下の3つ
224
+
225
+
226
+
227
+ - Shorthand property names
228
+
229
+ - Shorthand method names
230
+
231
+ - Computed property names
232
+
233
+
234
+
235
+ のコード例が挙げられていますが、これらのうち
236
+
237
+ ```javascript
238
+
239
+ {
240
+
241
+ init0,
242
+
243
+ init1,
244
+
245
+ init2
246
+
247
+ }
248
+
249
+ ```
250
+
251
+ は、1番目の `Shorthand property names` を使った書き方です。
252
+
253
+
254
+
255
+ 次に
256
+
257
+
258
+
259
+ > また、「initializers[str]();」これで関数を実行できるというやり方も今回初めて目にしたのですが
260
+
261
+ こういう方法は何か名前がついていますか? 
262
+
263
+
264
+
265
+ についてですが、ちょっと端折った書き方をしてしまったので、何か特別なことをやってるように見えてしまったかもしれませんが、`initializers[str]();` をもう少し丁寧に書くと、以下になります。
266
+
267
+
268
+
269
+ ```javascript
270
+
271
+ const fn = initializers[str];
272
+
273
+
274
+
275
+ fn();
276
+
277
+ ```
278
+
279
+ 上記では
280
+
281
+ (ⅰ) 変数 `fn` に、 `initializers[str]` を代入する。
282
+
283
+ (ⅱ) 上記の代入によって、変数 `fn` には関数が入ってくる想定なので、`fn()` で、この関数を実行する。
284
+
285
+ という2段階のことを行っており、それぞれに何か特別なことをやっているわけではないので
286
+
287
+
288
+
289
+ > 何か名前
290
+
291
+
292
+
293
+ というものがついているわけではなく、上記で、いったん `fn` に入れているのを、端折って書けば、
294
+
295
+ ```javascript
296
+
297
+ initializers[str]();
298
+
299
+ ```
300
+
301
+ というものになる、ということです。
302
+
303
+
304
+
305
+ 上記 (ⅰ)、(ⅱ) に関連する JavaScript の基礎知識あるいは概念としては、
306
+
307
+
308
+
309
+ (ⅰ) プロパティアクセサー
310
+
311
+
312
+
313
+ (ⅱ) javascript の関数は、第一級オブジェクト
314
+
315
+
316
+
317
+ が挙げられます。以下、各々について説明します。
318
+
319
+
320
+
321
+
322
+
323
+ **(ⅰ) プロパティアクセサー**
324
+
325
+
326
+
327
+ MDN のプロパティアクセサーの説明は以下です。
328
+
329
+
330
+
331
+ - MDN: [プロパティアクセサー](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Property_Accessors)
332
+
333
+
334
+
335
+
336
+
337
+ 上記に以下のように書かれています。
338
+
339
+
340
+
341
+ > プロパティアクセサーはオブジェクトのプロパティへのアクセスを提供するもので、ドット表記法またはブラケット表記法を使用します。
342
+
343
+
344
+
345
+ 今回のご質問では、 `"init0"` または `"init1"`, `"init2"` という文字列が入っている想定の変数 `str` があったとして、`initializers` のプロパティの中で、`str`の値と一致するプロパティの値が欲しいわけですが、その際にはドット表記法で `initializers.str` **とは書けず、 ** ブラケット表記法で、
346
+
347
+ ```javascript
348
+
349
+ initializers[str]
350
+
351
+ ```
352
+
353
+ と書きます。
354
+
355
+
356
+
357
+ **(ⅱ) JavaScript の関数は、第一級オブジェクト**
358
+
359
+
360
+
361
+ MDN の[関数の説明](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions) の冒頭、2段落目に以下のように書かれています。
362
+
363
+
364
+
365
+ > JavaScript において、関数は第一級オブジェクトです。すなわち、関数はオブジェクトであり、他のあらゆるオブジェクトと同じように操作したり渡したりする事ができます。
366
+
367
+
368
+
369
+ また、 wikipedia の [第一級オブジェクトの説明](https://ja.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E7%B4%9A%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88) に、以下の記載があります。
370
+
371
+
372
+
373
+ > 第一級オブジェクトは概ね次のような性質をもつ。
374
+
375
+ > ・・・
376
+
377
+ > ・変数に格納可能である
378
+
379
+ > ・データ構造に格納可能である。
380
+
381
+ > ・・・
382
+
383
+
384
+
385
+ JavaScript の関数が上記の性質を持つことを踏まえて、
386
+
387
+
388
+
389
+ ```javascript
390
+
391
+ function init0() {
392
+
393
+  ・・・
394
+
395
+ }
396
+
397
+ ```
398
+
399
+ と宣言された関数 `init0` を実行することを考えます。最も簡単には、`init0`を実行するには
400
+
401
+ ```javascript
402
+
403
+ init0();
404
+
405
+ ```
406
+
407
+ と書けばよいのですが、その他にも、以下のように `init0` を 変数`f` に代入して、 `f(); `と書くことでも実行できます。
408
+
409
+ ```javascript
410
+
411
+ const f = init0;
412
+
413
+
414
+
415
+ f();
416
+
417
+ ```
418
+
419
+
420
+
421
+ あるいは、`init0` を、何らかのオブジェクトのプロパティの値にして、そのオブジェクトのメソッドとして実行することもできます。
422
+
423
+
424
+
425
+ ```javascript
426
+
427
+ const obj = { f: init0 };
428
+
429
+
430
+
431
+ obj.f();
432
+
433
+ ```
434
+
435
+
436
+
437
+ このように、 `init0` を他の変数に入れたり、何らかのオブジェクトのプロパティの値にしたりできますし、また、何らか別の関数が return する値の中で、 init0 を使うこともできます。たとえば以下の関数
438
+
439
+
440
+
441
+ ```javascript
442
+
443
+ function getInitializers() {
444
+
445
+ return [ init0, init1, init2 ];
446
+
447
+ }
448
+
449
+ ```
450
+
451
+
452
+
453
+ は、 長さが3で、要素が `init0`, `init1`, `init2` であるような配列を返します。この関数`getInitializers()` を呼ぶ側では、
454
+
455
+
456
+
457
+ ```javascript
458
+
459
+ const initFuncs = getInitializers();
460
+
461
+
462
+
463
+ initFuncs[1](); // init1() が実行される。
464
+
465
+ ```
466
+
467
+
468
+
469
+ といったように使います。
470
+
471
+
472
+
473
+ 関数が第一級オブジェクトであるので、分かり易くいうと、
474
+
475
+
476
+
477
+ **関数を変数やプロパティや配列の要素に入れて、どこにでも持ち運べる。**
478
+
479
+
480
+
481
+ といった感じです。
482
+
483
+
484
+
485
+
486
+
487
+ #### (2) 参考資料、図書について
488
+
489
+
490
+
491
+
492
+
493
+ 先述した **(1) コードについての説明** を整理すると、以下の3つのトピックがありました。
494
+
495
+
496
+
497
+ **(A) Shorthand property names (ECMAScript 2015)**
498
+
499
+ **(B) プロパティアクセサー**
500
+
501
+ **(C) 関数が第一級オブジェクトであること**
502
+
503
+
504
+
505
+ 上記3点についての参考資料、推薦図書を以下に挙げます。
506
+
507
+
508
+
509
+ (A) の参考資料は後述します。
510
+
511
+ (B) プロパティアクセサー と、(C) 関数が第一級オブジェクトであることについては、ECMAScript 2015よりも前からJavaScript に備わっている、基礎事項に含まれる項目ですが、これらについてきちんと理解をするための参考書として、個人的に推薦するのは、以下です。
512
+
513
+
514
+
515
+ - [「開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質」オライリージャパン](https://www.amazon.co.jp/dp/487311621X/)
516
+
517
+
518
+
519
+ 基礎の何らかのトピックを習得しようとするときに、自分でそのトピックだけにフォーカスした(短い)コードを書いてその結果を確認し、さらにコードを修正して結果の違いを理解するという作業が欠かせませんが、白紙から自分でその理解のためのコードを書くのは大変です。この本は、そのようなコードを多数、サンプルで提供してくれる点がお勧めの理由です。また、内容の濃さに比べて薄い本なのも、取り組みやすいです。
520
+
521
+
522
+
523
+ 手前味噌で恐縮ですが、この本に掲載されているサンプルコードの一覧を以下に作成しています。
524
+
525
+
526
+
527
+ - Qiita: [「開眼!JavaScript」サンプルコード#1/4 第1-4章](https://qiita.com/jun68ykt/items/5aee04682f95f2354398) (※5章以降は、先のページからリンクされた別記事です。)
528
+
529
+
530
+
531
+ 上記の記事には、この本のサンプルコードへのリンクを一覧しているので、各節のタイトルとコードを見て頂けると、どんな本か、ざっくりつかめると思います。ちなみに
532
+
533
+
534
+
535
+ **(B) プロパティアクセサー**
536
+
537
+
538
+
539
+ については、この本では
540
+
541
+
542
+
543
+ - 2.3節 ドット記法とブラケット記法でオブジェクトのプロパティにアクセス
544
+
545
+
546
+
547
+ に説明とサンプルコードがあります。また、
548
+
549
+
550
+
551
+ **(C) 関数が第一級オブジェクトであること**
552
+
553
+
554
+
555
+ については、
556
+
557
+
558
+
559
+ - 4.6節 JavaScriptの関数は第一級関数
560
+
561
+
562
+
563
+ に説明とサンプルコードが載っています。
564
+
565
+
566
+
567
+ ただ、この本について一つ、難点があります。上記の Qiita の記事に一覧したリンクのどれかをクリックして頂くと分かりますが、サンプルコードは jsfiddle に作成されており、 console.log の出力を見ることでコードの動作を確認することになっており、発刊当初はもちろん console.log で動作確認できていたのですが、今現在では console に出力するための firebug-lite-debug が動かないので、コードを自分の手元の開発環境にコピペするか、javascriptのコードを動かせる他のサービス、例えばCodePenなどにコピペするかしないと console.logへの出力で動作の確認ができなくなっています。そこは一手間かかってしまいますが、その手間を差し引いても、重要な概念について、サンプルコードを多数提供してくれるこの本は良書と思います。
568
+
569
+
570
+
571
+ 次に
572
+
573
+
574
+
575
+ **(A) Shorthand property names (ECMAScript 2015)**
576
+
577
+
578
+
579
+ についての参考図書を挙げるとすると、ECMAScript 2015 以降に新たに導入された書き方や機能に集中した内容となっている書籍として、以下をお勧めします。
580
+
581
+
582
+
583
+ - [「入門 JavaScript プログラミング」翔泳社](https://www.amazon.co.jp/%E5%85%A5%E9%96%80JavaScript%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-JD-Isaacks/dp/479815864X)
584
+
585
+
586
+
587
+ この本は、 上記のとおり邦題が「入門 JavaScript プログラミング」ですが、これは原著のタイトルである
588
+
589
+
590
+
591
+ Get Programming with JavaScript **Next**
592
+
593
+
594
+
595
+ の末尾にある "Next" を訳しきれていないので、まったくの入門書に誤解されてしまいますが、原著の副題は
596
+
597
+
598
+
599
+ New feature of ECMAScript 2015, 2016 and beyond
600
+
601
+
602
+
603
+ です。
604
+
605
+ また、和訳版まえがきの「本書について」には、こう書かれています。
606
+
607
+
608
+
609
+ > 本書は、ES2015 以降に導入された新しい機能をこれから学ぼうとしているJavaScript プログラマのために書かれている。
610
+
611
+
612
+
613
+ また、「本書の対象読者」には以下のようにも書かれています。
614
+
615
+
616
+
617
+ > 従来のJavaScriptを使って問題なくプログラミングを行えることが前提となるが、・・・
618
+
619
+
620
+
621
+ 上記にある、「従来のJavaScriptを使って問題なくプログラミングを行えること」 の補強のために、先の「開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質」をお勧めする次第です。
622
+
623
+
624
+
625
+ ただ、この本で、ECMAScript 2015 以降の書き方のすべてが網羅されているかというと、そのような総覧ではないので、一覧としては個人的には以下を使うことがあります。
626
+
627
+
628
+
629
+ - [ECMAScript 6 — New Features: Overview & Comparison](http://es6-features.org)
630
+
631
+
632
+
633
+
634
+
635
+ 上記のサイトでは、先に挙げた
636
+
637
+ (A) Shorthand property names (ECMAScript 2015)
638
+
639
+ は、 以下に説明とコード例があります。
640
+
641
+
642
+
643
+ - [http://es6-features.org/#PropertyShorthand](http://es6-features.org/#PropertyShorthand)
644
+
645
+
646
+
647
+ 上記のサイトでは、「Ecmascript 5 以前ではこう書いていたけれど Ecmascript 2015(ES6)ではこのように書けるようになった」という、新旧のコード対比ができるので分かり易いです。
648
+
649
+
650
+
651
+ 以上、参考になれば幸いです。

3

テキスト修正

2019/09/16 14:18

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -68,11 +68,11 @@
68
68
 
69
69
 
70
70
 
71
- または、WEBブラウザで動かしているコードのでしたら、グローバルオブジェクトを得るのに、
71
+ または、ご質問のコードは、WEBブラウザで動かコードですので、グローバルオブジェクトを得るのに、
72
72
 
73
73
  `var global = (function(){ return this; })();`
74
74
 
75
- とまわりくどいことをせずに、 グローバルオブジェクトが `window` であること分かっているので、
75
+ とまわりくどいことをせずに、 グローバルオブジェクトが `window` であること分かっているので、
76
76
 
77
77
 
78
78
 

2

テキスト修正

2019/09/15 02:27

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -65,3 +65,23 @@
65
65
  ```
66
66
 
67
67
  - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/KKPBKbN?editors=0012](https://codepen.io/jun68ykt/pen/KKPBKbN?editors=0012)
68
+
69
+
70
+
71
+ または、WEBブラウザで動かしているコードなのでしたら、グローバルオブジェクトを得るのに、
72
+
73
+ `var global = (function(){ return this; })();`
74
+
75
+ とまわりくどいことをせずに、 グローバルオブジェクトが `window` であることが分かっているので、
76
+
77
+
78
+
79
+ ```javascript
80
+
81
+ window['init0']();
82
+
83
+ ```
84
+
85
+ でもよいです。
86
+
87
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/eYOjgjW?editors=0012](https://codepen.io/jun68ykt/pen/eYOjgjW?editors=0012)

1

テキスト修正

2019/09/15 02:20

投稿

jun68ykt
jun68ykt

スコア9058

test CHANGED
@@ -39,3 +39,29 @@
39
39
 
40
40
 
41
41
  以上参考になれば幸いです。
42
+
43
+
44
+
45
+ ---
46
+
47
+ ### 追記
48
+
49
+
50
+
51
+ (あまり筋の良い方法とは思いませんが、)以下のようにグローバルオブジェクトのプロパティとして各関数を取り出して、これを実行する、ということも可能です。
52
+
53
+
54
+
55
+ ```
56
+
57
+ var global = (function(){ return this; })();
58
+
59
+ var str = 'init0';
60
+
61
+
62
+
63
+ global[str]();
64
+
65
+ ```
66
+
67
+ - **動作確認用CodePen:** [https://codepen.io/jun68ykt/pen/KKPBKbN?editors=0012](https://codepen.io/jun68ykt/pen/KKPBKbN?editors=0012)