質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

3回答

3013閲覧

配列に格納した文字列(※関数名)をeval()を使わずに実行したい

aKusano

総合スコア3763

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2019/09/14 06:53

前提・実現したいこと

こちらの質問でアドバイスをいただき、
ページ内に配置された複数のcanvasに対して、該当のcanvasが画面内に入った時に
アニメーションを開始するスクリプトを書きました。

canvasアニメーションはAnimateCCから書き出したもので、実行するのに
init0(),
init1(),
init2()...
といった連番の関数を呼び出す必要があります。

eval()を使えばやりたいことは実行できているのですが、
使わないほうが推奨されるやり方なのであればそのようにしたいです。
ただ、そもそも今回のようなケースでeval()を使った場合に、
どのような問題が生じるのか?ということ自体が分からないので
できればeval()を使わない方が良い理由なども教えていただけますと助かります。

試したこと

eval()を使わずに文字列で関数を実行する方法などをいろいろ検索しましたが、
今回のように配列の中に格納されている文字列(関数名)を取り出してそのまま関数として実行することを前提としたサンプルは無かったため、うまく応用することができませんでした。

該当のソースコード

JavaScript

1 var $trigger = $("canvas"); 2 //var windowHeight = $(window).height(); 3 var num = $trigger.length; 4 var initArray = []; 5 var initFlag = []; 6 7 for(var i = 0; i < num; i++){ 8 var str = 'init'+i+'()'; 9 initArray.push(str); 10 initFlag.push('false'); 11 } 12 13 14 $(window).on("scroll",function(){ 15 var windowHeight = $(window).height(); 16 var scroll = $(window).scrollTop(); 17 18 $trigger.each(function(i){ 19 var pos = $(this).offset().top; 20 if (scroll > pos - windowHeight/2){ 21 if(initFlag[i] == 'false'){ 22 eval(initArray[i]); 23 initFlag.splice(i,1,'true'); 24 }else{ 25 return; 26 } 27 28 } 29 }); 30 }).scroll();

HTML

1<html> 2<head> 3<meta charset="UTF-8"> 4<meta name="authoring-tool" content="Adobe_Animate_CC"> 5<title>sample</title> 6<!-- write your code here --> 7<script src="https://code.createjs.com/createjs-2015.11.26.min.js"></script> 8<script src="assetsratio_pc.js"></script> 9<script src="assetsratio_sp.js"></script> 10<script src="measuresratio.js"></script> 11<script src="top.js"></script> 12<script src="common.js"></script> 13 14</head> 15<body> 16 17 <div id="animation_container0"> 18 <canvas id="canvas0" width="260" height="260"></canvas> 19 <div id="dom_overlay_container0"></div> 20 </div> 21 22 23 <div style="height: 1000px">他のコンテンツ</div> 24 25 <div id="animation_container1"> 26 <canvas id="canvas1" width="844" height="460"></canvas> 27 <div id="dom_overlay_container1"></div> 28 </div> 29 30 <div style="height: 1000px">他のコンテンツ</div> 31 32 <div id="animation_container2"> 33 <canvas id="canvas2" width="345" height="397"></canvas> 34 <div id="dom_overlay_container2"></div> 35 </div> 36 37</body> 38</html>

補足情報

init0(), init1(), init2()... のそれぞれの中身自体は
別の外部JSファイルに記載されています。
こちらの質問のtop.jsがそれです。

よろしくお願い申し上げます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

こんにちは

関数 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を実行するには、

javascript

1init0();

と書けばよいのですが、その他にも、以下のように 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) 関数が第一級オブジェクトであること

については、

  • 4.6節 JavaScriptの関数は第一級関数

に説明とサンプルコードが載っています。

ただ、この本について一つ、難点があります。上記の 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/14 07:53

編集2019/09/16 17:02
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aKusano

2019/09/15 20:08

> initializers[str](); にて、 関数 init0() を実行できます。 確かにそのようにすればeval()を使わなくても関数initn()を実行できました! …が、不勉強でお恥ずかしいのですが今回教えていただいた方法について 仕組みが今ひとつ理解できません…。 var xxx = {}; これは連想配列またはオブジェクトを表しているという理解なのですが、この場合、中に入るのはkey: value のペアになるのではないのでしょうか?? 教えていただいたものだとinit0,init1,init2 という文字の配列のように見えます。。。 また、「initializers[str]();」これで関数を実行できるというやり方も今回初めて目にしたのですが こういう方法は何か名前がついていますか? 調べたくてもどういうキーワードで検索したら 良いのか分からなくて……。 今回教えていただいた手法をちゃんと理解するのに役立つ参考サイト・文献などがありましたら ご教授いただけますと助かります…!
jun68ykt

2019/09/16 14:20

@aKusanoさん コメントありがとうございます。返答を、回答のほうに追記2として書きました。参考になれば幸いです。
jun68ykt

2019/09/16 15:22

追記2で「開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質」をお勧めしましたが、この本をもし手に取られて読み始めたときに、学習効果の実感として、おおざっぱにいうと以下のA, Bの2通りが考えられます。  A:「今まで自分の中で整理できてなかった JavaScript の重要な項目が、コードと共に整理されていて良い本だ」  B: 「サンプルコードが多い割に説明があっさりし過ぎて、JavaScript の基礎が身につく感じがしない」 もし(不運にも) B であった場合は、 JavaScript を初めて学習したときの教材は何で、その際にどの程度深くやったのかについて振り返り、その振り返りの内容によっては、この先発展的なことに取り組むためには、JavaScript の基礎について、入門者ではないレベルを要求される教材を使いながら、ひと通り取り組む必要があるかもしれません。
aKusano

2019/09/16 21:09

追記の解説、ありがとうございました!!! 大変丁寧な解説で、今回の部分について何をしているのかについては 大体理解できたと思います…! また、参考書籍・文献についてもご提示ありがとうございます。 実は「開眼!〜」については数年前に一度購入して読んだことがあったのですが、 「関数はオブジェクトである」ということなど、 その時は言葉ヅラ的には何となく理解できるような気がしたのですが、 やはり自分の中に落とし込むことができず、読み始めて10分で閉眼しはじめる始末でした…(汗) (翻訳口調が苦手ということもあるかもしれません) ちなみにJavaScriptに初めて触れたのはもうかれこれ20年近く前で、DOM操作ができるようになる以前の第一世代の時です。その時は何かまとめて入門書を読んだりしたわけではなく、雑誌等に乗っているサンプルコードや、他のサイトで使われているコードを見様見真似で改造したりして何とか動かしていた程度で、 とりあえず変数や関数、条件分岐、ループ処理、配列くらいのごく初歩的な概念だけは理解したものの その後「JavaScriptは悪!」という時代の空気に便乗して長らく離れておりました。 JavaScriptで再び何かをやるようになったきっかけはjQueryで、 そこで初めて「Webサイトで自分のつくりたいものを自力で作る」ということを多少できるようになった次第です。 当然、jQueryの知識だけでは限界があるので生のJavaScriptも勉強しなくては、と思ったのですが、その時には既に昔のJavaScriptとは別物になっていて「???」となり、更にやたらと進化が激しくてエスカレーターに乗るタイミングが計れないおばあちゃんよろしく、「え?どこから手を付ければ…??」という状態になってるのが今という感じです。 紹介していただいた2冊目の本は、新しい仕様に特化して違いを解説しているとのことなので、 購入して勉強してみたいと思います。「開眼!〜」も、今はどこかにしまい込んでしまってますが 引っ張り出してきてもう一度読んで見ようと思います。 (何となく今なら前より理解できそうな気がします。) このたびはありがとうございました! また何かありましたら質問させていただくこともあるかと思いますが、 その際はよろしくお願い申し上げます。
aKusano

2019/09/17 02:55

補足ですが、今回IE11も対象なのでES6の書式・構文についてはES5に ダウングレードする必要がありました。 まだES5で止まっていてbabelなどのトランスパイル環境を用意していないので、 一部手動でES5の書式に書き直して実装いたしましたのでご報告いたします。 本格的にES6勉強するならbabelも入れないと駄目ですね…。
jun68ykt

2019/09/18 12:53

こんにちは。 > 実は「開眼!〜」については数年前に一度購入して読んだことがあったのですが、 おお!そうでしたか。 > やはり自分の中に落とし込むことができず、読み始めて10分で閉眼しはじめる始末でした…(汗) なるほどですね。「開眼!〜」は、それまでにどれくらい基礎固めを体系的に取り組んだかが問われる本かなと思います。 先のコメントで > もし(不運にも) B であった場合は、 JavaScript を初めて学習したときの教材は何で、 > その際にどの程度深くやったのかについて振り返り、その振り返りの内容によっては、 > この先発展的なことに取り組むためには、JavaScript の基礎について、入門者ではない > レベルを要求される教材を使いながら、ひと通り取り組む必要があるかもしれません。 と書きましたが、上記の「入門者ではないレベルを要求される教材」としては、以下のような書籍が挙げられます。  (A) JavaScript 第6版 (オライリージャパン)  (B) 徹底マスター JavaScriptの教科書 (ソフトバンククリエイティブ)  (C) 改訂新版JavaScript本格入門(技術評論社)  (D) 初めてのJavaScript 第3版 - ES2015以降の最新ウェブ開発(オライリージャパン)  (E) パーフェクトJavaScript (技術評論社) 私は(もうかなり昔ですが)JavaScriptの基礎学習の際には(A)を通読しました。 (B)〜(E) も手元に置いてあり、JavaScript の重要な概念(たとえば、クロージャーだったり、プロトタイプだったり)の説明をどのように書いているかの参考にしています。 (A) から (E) の中で、aKusanoさんにお勧めするとすれば、aKusanoさんは、HTMLやCSSに関して高いスキルをお持ちで講師もなさっており、かつ、初期のJavaScriptの印象として > その後「JavaScriptは悪!」という時代の空気に便乗 されていたという経緯から、  (D) 初めてのJavaScript 第3版 - ES2015以降の最新ウェブ開発(オライリージャパン)   が一番、しっくりくるのではないかと思います。 筆者のまえがきに以下のように書いてあるところは、共感頂けるのではと思いました。 ↓↓↓ 引用ここから ↓↓↓  この本はJavaScript 関連で私が書いた2冊目の本ということになりますが、「思いがけない展開になったものだ」と自分自身でも驚いているところです。というのは、2012年頃まで、JavaScript に対して偏見をもっていたからです。自分自身の「転向」に少し戸惑いを感じているのです。  そんなプログラマーは今でも少なくないのかもしれませんが「JavaScriptなんて、アマチュアプロ グラマーが真っ先に手を出すオモチャみたいな言語さ」という印象をもっていたのです。 ・・・(中略)・・・ ・・・しかし、後継となったES2015では多くの問題点が解消され、以前にも増して開発がしやすい素晴らしい 言語になっているのです。 ↑↑↑ 引用ここまで↑↑↑ 以下のアマゾンのページで https://amzn.to/2kPAzWn 上記の、筆者によるまえがき、翻訳者のまえがき、目次を確認できます。 ちなみに、訳者代表の武舎広幸さんは、JavaScriptの 入門講座を開催されているそうで、受講者さんにこの本を薦めるのは第2版までは少し難度が高すぎてためらっていたが第3版はお勧めできる、と訳者まえがきに書いてあります。 (D) などで基礎のおさらいをした後に > jQueryの知識だけでは限界があるので生のJavaScriptも勉強しなくては、 というモチベーションに応える一冊としては以下もお勧めです。 (F) JavaScript Ninjaの極意 ライブラリ開発のための知識とコーディング (翔泳社) この本の作者はJQueryの開発者のジョン・レシグさんで、原書第1版の訳本です。原書では第2版が出ており、そちらはES2015の文法も踏まえた内容になっていますが、上記の邦訳版は第1版の訳本で、コードはES5で書かれていますが、その点を踏まえても、 「スゴイJavaScript使いがコードを書くとき、JavaScriptのもつ特徴をどう生かすことを考えるのか」 を知ることができます。 > 本格的にES6勉強するならbabelも入れないと駄目ですね…。 そうですね。ES6 で新たに導入された書き方のコードが、どのようにES5のコードに置き換わるかを確認すると、より深い理解が得られると思います。 なお先のコメントで挙げた 「入門 JavaScript プログラミング」翔泳社 https://amzn.to/2kSx41j は、LESSON 1〜34 の全34セクションで構成されていますが、LESSON 2 は「Babelを使ったトランスパイル」というタイトルで babel について、一セクションを割いています。 以上、aKusanoさんの一助となれば幸いです。
aKusano

2019/09/19 18:25

追加のおすすめ書籍のご紹介、ありがとうございます!! 「入門 JavaScript プログラミング」翔泳社 は、早速購入して本日届いた次第です。 とりあえずBabelを導入してES6で書けるような環境を作るところから始めたいと思います!
jun68ykt

2019/09/21 07:52

ご連絡ありがとうございます。私のほうは、HTMLやCSSが苦手なので、aKusanoさんの回答で学ばせて頂きますね。今後ともよろしくお願い致します。
aKusano

2019/09/22 16:28

こちらこそよろしくお願いいたします。
guest

0

evalを使うよりは、こっちの方が多少安全です。
Function - JavaScript | MDN

ただ、以下のような性質があります。

Function コンストラクタによる関数の生成は、生成コンテキストにクロージャを作りません。つまり常にグローバルスコープで作成します。これを実行すると、 Function コンストラクタの呼び出し元のスコープは入らず、自身のローカル変数とグローバル変数だけにアクセスできます。これは関数式のコードに eval を使うのとは異なっています。

Function - JavaScript | MDN

なので、グローバル変数を多用せざるを得なくなりますから、個人的には今回のケースであればevalの方が多少マシかと思います。
evalの危険性は主に、意図しないコードが混入することですから、外部入力が文字列に挿入されなければ「めちゃめちゃヤバい」という程ではなく、「ちょっとドキドキ」程度のリスクではないかな、と個人的には思います。

投稿2019/09/14 08:02

編集2019/09/14 08:03
Lhankor_Mhy

総合スコア36074

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aKusano

2019/09/15 19:23

> 外部入力が文字列に挿入されなければ 一応どこかから入力&投稿するような場面で使っているわけではないので大丈夫だとは思うのですが、ちょっとドキドキ程度のリスクはやっぱりあるってことなんですよね…。 でもevalの方が多少マシ、という選択肢もあることは心強いです。 他の方法でどうにもできなかった場合にはevalのまま残すのもやむを得ない、ということで、ひとまず他の方法ももう少しあたってみたいと思います。
guest

0

実行するのに

といった連番の関数を呼び出す必要があります。

その設計が間違っています。

関数名に数字を含めるのでなく、関数の配列にしましょう。

投稿2019/09/14 07:23

otn

総合スコア84505

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aKusano

2019/09/14 07:48 編集

つまり今のように連番が振られた関数名を配列にいれておいて、 それを関数として実行させることはeval()を使わない限り不可能、 ということでよろしいでしょうか?
otn

2019/09/14 10:40

そうでうすね。evalないしそれと同等の物が必要です。
aKusano

2019/09/15 19:18

なるほど!ありがとうございます。 どうりで調べてみても糸口が見つからないわけですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問