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

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

ただいまの
回答率

90.62%

  • JavaScript

    15883questions

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

evalで連結作成した動的変数の存在判断

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 133

Yasu0421

score 4

毎度お世話になっております。
例えば、以下の様にevalを用いて動的に作成した変数があるとします

for(var i=0; i<5; i++){
  eval("var test"+i+"=" i*10);
}


この言わば動的?に作成した変数 test0~test4は上記で初期化されているので
存在しますが、上記以外の例えば test5は存在していませんのでundefinedと
なります。
この存在判断を行うために例えば

for(var j=0; j<6; j++){
  if(typeof("test"+j) === "undefined"){
    aleart("test"+j+"undefined");
  )
}


等としても、上記の判断には合致することなく、test5はalertと出しません。

上記のような連結して作成した変数の存在判断を行うには
どのように対処したらよいのでしょうか?
ご教示いただければ幸いです。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+3

本題ではありませんが、'use strict';とした環境、あるいは自動でstrictとなる環境(モジュール内、class内など)では、evalで変数を外部に作ることができませんMDN)。

すでに述べたように、自動でstrictとなる環境も多くあるような状況なので、もはや非strictでしか動かないevalの挙動に頼るようなコードは、書くべきではないかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/06 11:25

    いつもご回答いただきありがとうございます。
    多角的な面からもご指摘いただき大変たすかります。
    しばしば、”evalは使うべきでない”と記載された記事も見かけますが、
    上記の観点が本質にあるのですね。
    ご助言いただきありがとうございます。

    キャンセル

  • 2018/06/06 11:29

    evalの問題点としては、

    * 変数名で変数を参照、(最悪は書き込み)する必要が出てくるので、最適化が効かず遅くなる
    * 外侮から値を投げ込まれると、思わぬコードが実行されてセキュリティリスクとなる

    などがあります。そして、「ローカル変数の名前」なんていうものは、関数の外からは誰も知る余地もない、作業用の符号でしかないものですので、「名前ごと生成して処理させる」こと自体、通常は必要になりません。

    キャンセル

  • 2018/06/06 11:34

    詳細なご説明ありがとうございました。
    他の手段についても検討してみるきっかけともなりました。
    ありがとうございました。

    キャンセル

checkベストアンサー

+2

typeof("test"+j)は"string"なので、alertがでることはないですね。

testを宣言したコンテクストに対して、チェックする感じですかね。
たとえば、ブラウザでこれだけやってるとしたら、typeof(window["test"+j])とするとか。

なぜこのようなことをするのかが分かりませんが、配列とかobject(連想配列)を使うとかしたほうがいいように思えます(test[i]とか)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/06 11:17

    ご回答ありがとうございます。
    ご提案いただいた内容で確認してみます。
    evalを使う理由ですが、質問させていただいた例では簡素化するために
    "test+i"といった表現を使用させていただきました。
    本来は、配列的ではなく、他の変数との組み合わせで生成された動的な
    変数となります。(説明が下手で申し訳ございませんがつたわりましたでしょうか?)
    まずはお礼まで

    キャンセル

  • 2018/06/06 11:18

    PHPなら get_defined_vars のように現在のコンテキストに存在する変数をすべて収集する機能があるので頑張れなくはないですが,JavaScript にはそれがないため window を使ってグローバル変数を使う手段のみになってしまいますね。できるだけグローバル変数を使うのは避けたいですね。私も配列やオブジェクトを使う方法を支持します。何か質問者さんは目的に対して手段を間違えているような気がします…

    キャンセル

  • 2018/06/06 11:19 編集

    >> 他の変数との組み合わせで生成された動的な変数となります。

    たぶんここがそもそも手段の選択ミスなような…
    質問は具体的に書くべきとは言われますが,今回の場合具体的すぎて手段が完全にロックされてしまっているように見えるので,もう少し抽象的に,上位の目的を書いていただけると理想的な回答ができるかもしれません。

    キャンセル

  • 2018/06/06 11:30

    いろいろとご指摘いただきありがとうございました。
    目的へたどり着くまでの手段・・・浅識な私にはまだまだ難しいですね
    勉強致します。
    で、結果としては、上手くいきました。
    大変たすかります。 手段に関してももう少し深堀してみます。
    有難うございました。

    キャンセル

+1

他の方もおっしゃっていますが、
eval関数 そもそもはあまり使わない方がいいものだと思いますし、
配列やオブジェクトでも十分やりたいことはできるはずです。

それでもどうしても

for(var i=0; i<5; i++){
  eval("var test"+i+"=" i*10);
}


この形を貫きたいのであれば、判定でもevalを使えばいいではないかと。。。

for(var j=0; j<6; j++){
  if(typeof(eval("test"+j)) === "undefined"){
    alert("test"+j+"undefined");
  )
}

しつこいようですが、おすすめはできない方法ですよ・・?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/06 11:41

    ご回答いただきありがとうございます。
    eval使用の件、心に響きました・・・
    で、判定でevalを使うのは既にトライしていたのですが、evalからエラーが帰ってきてしまい(例えばtest1 not definedなど)判定できませんでした。難しいですね。

    キャンセル

  • 2018/06/06 12:00

    なるほど。undefinedのものは、evalで実行時にエラーが出るんですね・・!試さずご提案すみません。それなら、

    if(eval("typeof(test"+j+")") === "undefined"){

    こうでしたね^^;

    キャンセル

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

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15883questions

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