こんにちは
関数 init__n__ () をまとめたオブジェクトを作っておくのはいかがでしょうか?
たとえば、 top.js のほうに、以下のようなオブジェクト
javascript
1var initializers = {
2 init0,
3 init1,
4 init2
5};
を作っておくと、 変数 str
に文字列 "init0"
が入っているときに
javascript
1initializers[str]();
にて、 関数 init0()
を実行できます。
以上参考になれば幸いです。
追記
(あまり筋の良い方法とは思いませんが、)以下のようにグローバルオブジェクトのプロパティとして各関数を取り出して、これを実行する、ということも可能です。
var global = (function(){ return this; })();
var str = 'init0';
global[str]();
または、ご質問のコードは、WEBブラウザで動かすコードですので、グローバルオブジェクトを得るのに、
var global = (function(){ return this; })();
とまわりくどいことをせずに、 グローバルオブジェクトが window
であることは分かっているので、
javascript
1window['init0']();
でもよいです。
追記2
質問者さまからのコメントを、以下
(1) コードについての説明
今回教えていただいた方法について仕組みが今ひとつ理解できません…。
(2) 参考資料、図書について
今回教えていただいた手法をちゃんと理解するのに役立つ参考サイト・文献など
の2点に分けて、それぞれに回答します。
(1) コードについての説明
以下について回答します。
教えていただいたものだとinit0,init1,init2 という文字の配列のように見えます。。。
また、「initializersstr;」これで関数を実行できるというやり方も今回初めて目にしたのですが
こういう方法は何か名前がついていますか?
まず、
教えていただいたものだとinit0,init1,init2 という文字の配列のように見えます。。。
についてです。
top.js
に、関数名が init
で始まる、以下の3つの関数が宣言されています。
javascript
1function init0() {
2 ・・・
3}
4
5function init1() {
6 ・・・
7}
8
9function init2() {
10 ・・・
11}
これらに対して、先の回答に書いた、var initializers
に代入している以下のオブジェクトリテラル
javascript
1{
2 init0,
3 init1,
4 init2
5}
は、以下
javascript
1{
2 init0: init0,
3 init1: init1,
4 init2: init2
5}
を省略した書き方です。このような省略した書き方ができるようになったのは ECMAScript 2015 からです。
MDN では、以下に説明があります。
上記のMDNの説明には、以下の3つ
- Shorthand property names
- Shorthand method names
- Computed property names
のコード例が挙げられていますが、これらのうち
javascript
1{
2 init0,
3 init1,
4 init2
5}
は、1番目の Shorthand property names
を使った書き方です。
次に
また、「initializersstr;」これで関数を実行できるというやり方も今回初めて目にしたのですが
こういう方法は何か名前がついていますか?
についてですが、ちょっと端折った書き方をしてしまったので、何か特別なことをやってるように見えてしまったかもしれませんが、initializers[str]();
をもう少し丁寧に書くと、以下になります。
javascript
1const fn = initializers[str];
2
3fn();
上記では
(ⅰ) 変数 fn
に、 initializers[str]
を代入する。
(ⅱ) 上記の代入によって、変数 fn
には関数が入ってくる想定なので、fn()
で、この関数を実行する。
という2段階のことを行っており、それぞれに何か特別なことをやっているわけではないので
何か名前
というものがついているわけではなく、上記で、いったん fn
に入れているのを、端折って書けば、
javascript
1initializers[str]();
というものになる、ということです。
上記 (ⅰ)、(ⅱ) に関連する JavaScript の基礎知識あるいは概念としては、
(ⅰ) プロパティアクセサー
(ⅱ) javascript の関数は、第一級オブジェクト
が挙げられます。以下、各々について説明します。
(ⅰ) プロパティアクセサー
MDN のプロパティアクセサーの説明は以下です。
上記に以下のように書かれています。
プロパティアクセサーはオブジェクトのプロパティへのアクセスを提供するもので、ドット表記法またはブラケット表記法を使用します。
今回のご質問では、 "init0"
または "init1"
, "init2"
という文字列が入っている想定の変数 str
があったとして、initializers
のプロパティの中で、str
の値と一致するプロパティの値が欲しいわけですが、その際にはドット表記法で initializers.str
**とは書けず、 ** ブラケット表記法で、
javascript
1initializers[str]
と書きます。
(ⅱ) JavaScript の関数は、第一級オブジェクト
MDN の関数の説明 の冒頭、2段落目に以下のように書かれています。
JavaScript において、関数は第一級オブジェクトです。すなわち、関数はオブジェクトであり、他のあらゆるオブジェクトと同じように操作したり渡したりする事ができます。
また、 wikipedia の 第一級オブジェクトの説明 に、以下の記載があります。
第一級オブジェクトは概ね次のような性質をもつ。
・・・
・変数に格納可能である
・データ構造に格納可能である。
・・・
JavaScript の関数が上記の性質を持つことを踏まえて、
javascript
1function init0() {
2 ・・・
3}
と宣言された関数 init0
を実行することを考えます。最も簡単に関数init0
を実行するには、
と書けばよいのですが、その他にも、以下のように init0
を 変数f
に代入して、 f();
と書くことでも実行できます。
javascript
1const f = init0;
2
3f();
あるいは、init0
を、何らかのオブジェクトのプロパティの値にして、そのオブジェクトのメソッドとして実行することもできます。
javascript
1const obj = { f: init0 };
2
3obj.f();
このように、 init0
を他の変数に入れたり、何らかのオブジェクトのプロパティの値にしたりできますし、また、何らか別の関数が return する値の中で、 init0 を使うこともできます。たとえば以下の関数
javascript
1function getInitializers() {
2 return [ init0, init1, init2 ];
3}
は、 長さが3で、要素が init0
, init1
, init2
であるような配列を返します。この関数getInitializers()
を呼ぶ側では、
javascript
1const initFuncs = getInitializers();
2
3initFuncs[1](); // init1() が実行される。
といったように使います。
関数が第一級オブジェクトであるので、分かり易くいうと、
関数を変数やプロパティや配列の要素に入れて、どこにでも持ち運べる。
といった感じです。
(2) 参考資料、図書について
先述した (1) コードについての説明 を整理すると、以下の3つのトピックがありました。
(A) Shorthand property names (ECMAScript 2015)
(B) プロパティアクセサー
(C) 関数が第一級オブジェクトであること
上記3点についての参考資料、推薦図書を以下に挙げます。
(A) の参考資料は後述します。
(B) プロパティアクセサー と、(C) 関数が第一級オブジェクトであることについては、ECMAScript 2015よりも前からJavaScript に備わっている、基礎事項に含まれる項目ですが、これらについてきちんと理解をするための参考書として、個人的に推薦するのは、以下です。
基礎の何らかのトピックを習得しようとするときに、自分でそのトピックだけにフォーカスした(短い)コードを書いてその結果を確認し、さらにコードを修正して結果の違いを理解するという作業が欠かせませんが、白紙から自分でその理解のためのコードを書くのは大変です。この本は、そのようなコードを多数、サンプルで提供してくれる点がお勧めの理由です。また、内容の濃さに比べて薄い本なのも、取り組みやすいです。
手前味噌で恐縮ですが、この本に掲載されているサンプルコードの一覧を以下に作成しています。
上記の記事には、この本のサンプルコードへのリンクを一覧しているので、各節のタイトルとコードを見て頂けると、どんな本か、ざっくりつかめると思います。ちなみに
(B) プロパティアクセサー
については、この本では
- 2.3節 ドット記法とブラケット記法でオブジェクトのプロパティにアクセス
に説明とサンプルコードがあります。また、
(C) 関数が第一級オブジェクトであること
については、
に説明とサンプルコードが載っています。
ただ、この本について一つ、難点があります。上記の Qiita の記事に一覧したリンクのどれかをクリックして頂くと分かりますが、サンプルコードは jsfiddle に作成されており、 console.log の出力を見ることでコードの動作を確認することになっており、発刊当初はもちろん console.log で動作確認できていたのですが、今現在では console に出力するための firebug-lite-debug が動かないので、コードを自分の手元の開発環境にコピペするか、javascriptのコードを動かせる他のサービス、例えばCodePenなどにコピペするかしないと console.logへの出力で動作の確認ができなくなっています。そこは一手間かかってしまいますが、その手間を差し引いても、重要な概念について、サンプルコードを多数提供してくれるこの本は良書と思います。
次に
(A) Shorthand property names (ECMAScript 2015)
についての参考図書を挙げるとすると、ECMAScript 2015 以降に新たに導入された書き方や機能に集中した内容となっている書籍として、以下をお勧めします。
この本は、 上記のとおり邦題が「入門 JavaScript プログラミング」ですが、これは原著のタイトルである
Get Programming with JavaScript Next
の末尾にある "Next" を訳しきれていないので、まったくの入門書に誤解されてしまいますが、原著の副題は
New feature of ECMAScript 2015, 2016 and beyond
です。
また、和訳版まえがきの「本書について」には、こう書かれています。
本書は、ES2015 以降に導入された新しい機能をこれから学ぼうとしているJavaScript プログラマのために書かれている。
また、「本書の対象読者」には以下のようにも書かれています。
従来のJavaScriptを使って問題なくプログラミングを行えることが前提となるが、・・・
上記にある、「従来のJavaScriptを使って問題なくプログラミングを行えること」 の補強のために、先の「開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質」をお勧めする次第です。
ただ、この本で、ECMAScript 2015 以降の書き方のすべてが網羅されているかというと、そのような総覧ではないので、一覧としては個人的には以下を使うことがあります。
上記のサイトでは、先に挙げた
(A) Shorthand property names (ECMAScript 2015)
は、 以下に説明とコード例があります。
上記のサイトでは、「Ecmascript 5 以前ではこう書いていたけれど Ecmascript 2015(ES6)ではこのように書けるようになった」という、新旧のコード対比ができるので分かり易いです。
以上、参考になれば幸いです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/15 20:08
2019/09/16 14:20
2019/09/16 15:22
2019/09/16 21:09
2019/09/17 02:55
2019/09/18 12:53
2019/09/19 18:25
2019/09/21 07:52
2019/09/22 16:28