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

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

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

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

Q&A

解決済

5回答

2286閲覧

インデックスiを含む変数のfor文による動的な変数宣言の仕方【JavaScript】

WeilSpinor

総合スコア170

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

JavaScript

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

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

0グッド

0クリップ

投稿2019/03/30 08:26

編集2019/03/30 08:30

タイトルの通りのことを質問いたします。
想定として、以下のような変数名の5つの変数
cBack1、cBack2、cBack3、cBack4、cBack5
を宣言して、それぞれにid名が同じHTMLエレメントを代入することを考えます。

evalを使うと良い、とあり、以下のようにためしたのですが、

javascript

1for(var i=1;i<=5;i++){//インデックスを含む変数のfor文による動的な変数宣言 2 eval("var cBack"+i) = document.getElementById("cBack"+i); 3 console.log(eval("cBack"+i)); 4};

以下のエラー

Uncaught ReferenceError: Invalid left-hand side in assignment

が出て、どうやらこのような変数宣言は許されないようです。
なにか良い方法はないでしょうか?

ご回答お待ちしております。

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

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

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

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

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

maisumakun

2019/03/30 08:37

どうしても「動的に変数名を指定する」必要はありますか(配列やオブジェクトで意図した実装はできませんか)?
WeilSpinor

2019/03/30 08:49

先ほど気づいた(ご回答を頂いて)のですが、配列をつかえばできますね。 id名と変数名を一致させる、という慣習があることを考えると(それと私の趣味趣向的には) 「配列を使わなくてもできないのだろうか?」 とも思いますが、難しいようでしたら、これで良いことにしようと思います。 実用上は問題ないと思うので…。
guest

回答5

0

document.getElementById("cBack"+i) という処理を作っているということは

html

1<element id="cBack1"></element> 2<element id="cBack2"></element> 3<element id="cBack3"></element> 4<element id="cBack4"></element> 5<element id="cBack5"></element>

というような、HTMLを書いているということになりますが、そもそも連番でIDを作らなきゃいけないということ自体がクソ設計 です。

id は文字通り、ただ一つの固有の識別情報なので、囚人のような番号を付けるものではありません

以下のように、Classでアクセスすると、要素が増えてもコピペで済むし、連番を誤って重複させてしまうこともありません。

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div> 9 <ul> 10 <li class="li">list-1</li> 11 <li class="li">list-2</li> 12 <li class="li">list-3</li> 13 <li class="li">list-4</li> 14 </ul> 15 </div> 16 <script> 17 var lists = document.getElementsByClassName('li'); 18 for (var i = 0; i < lists.length; i++) { 19 console.log(lists[i].innerText); 20 } 21 </script> 22 </body> 23</html>

イベントを追加する場合も以下のようにすることで簡潔なコードになります。

html

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 </head> 7 <body> 8 <div> 9 <ul> 10 <li class="li">list-1</li> 11 <li class="li">list-2</li> 12 <li class="li">list-3</li> 13 <li class="li">list-4</li> 14 </ul> 15 </div> 16 <script> 17 var lists = document.getElementsByClassName('li'); 18 for (var i = 0; i < lists.length; i++) { 19 lists[i].addEventListener('click', function(){ 20 alert(this.innerText); 21 }); 22 } 23 </script> 24 </body> 25</html>

投稿2019/03/30 08:43

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ベストアンサー

グローバル変数

それぞれにid名が同じHTMLエレメントを代入することを考えます。

そんな事をせずとも、id属性を持つ要素ノードはグローバル変数に格納される仕様です(HTML Standard)。
ただし、JavaScriptで認められる識別子名に準拠していなければ、グローバル変数化されず、同名グローバル変数が定義されれば衝突するので、getElementById による参照が推奨されます。

eval is evil

evalを使うと良い、とあり、以下のようにためしたのですが、

eval() によるローカル変数定義はStrict Modeでは使えないという問題があります。
他、様々な点から eval は推奨されていない為、(必要であれば)配列による変数定義に切り替える事をお勧めします。

Selectors API

HTMLを変更しないのであれば、[att^=val]前方一致してNodeListを得る方法があります。

最も、私なら、class="cback" を定義して、classセレクタ(.cback)で参照する方法を採用します。

更新履歴

  • 2019/03/30 17:51 「Selectors API」を追記
  • 2019/03/30 17:57 querySelectorAll, classセレクタを追記

Re: WeilSpinor さん

投稿2019/03/30 08:41

編集2019/03/30 08:57
think49

総合スコア18162

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

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

WeilSpinor

2019/03/30 08:52

ご回答ありがとうございます。 >そんな事をせずとも、id属性を持つ要素ノードはグローバル変数に格納される仕様です そんな変数があるんですね?知りませんでした。 使い方を調べてみようと思います。
think49

2019/03/30 08:53

親記事にも書きましたが、グローバル変数は推奨しません。 また、「Selectors API」を親記事に追記しました。 私ならこれを使います。
guest

0

「配列を使わなくてもできないのだろうか?」

とも思いますが、難しいようでしたら、これで良いことにしようと思います。

「難しい」というより、「evalを使って実装するほうがデメリットが大きい」のです。

  • セキュリティ上の問題が起きる危険がある
  • 最適化が効かず遅くなる
  • Strictモードで動作が変化するなど、互換性に問題がある

投稿2019/03/30 08:58

maisumakun

総合スコア145183

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

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

0

どのようなことをされたいのか分かりませんが、普通に配列に格納すればよいのでは?

js

1var elements = [] 2for (var i=1; i<=5; i++) { 3 elements.push(document.getElementById("cBack"+i)); 4}; 5console.log(elements)

本題とは関係ないですが、上記の処理は、もし自分であれば ES6 の記法を使って書きますね〜
こちらの方が、再代入が少ないので

js

1const elements = Array(5) 2 .fill(0) 3 .map((_, i) => document.getElementById(`${cBack}${i + 1}`)); 4console.log(elements);

投稿2019/03/30 08:41

KazuyaGosho

総合スコア38

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

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

WeilSpinor

2019/03/30 08:45

ご回答ありがとうございます。参考にさせていただきます。 配列は盲点でした。 配列を使わずともできないのだろうか?、とも思いましたが、 もはやそこは趣味の問題なので、そこはあまりこだわらないでおきます
KazuyaGosho

2019/03/30 09:03

確かにそれは趣味ですね笑
guest

0

evalを使う意味がないですが、そもそものエラーはevalの構文を分かってないことなんで、後の訪問者のためにもどう使えばevalできたかを書いておきます。

javascript

1for(var i=1;i<=5;i++){//インデックスを含む変数のfor文による動的な変数宣言 2 eval("var cBack"+i+ " = document.getElementById('cBack" + i+ "');"); 3 eval("console.log(cBack"+i+");"); 4}

投稿2019/03/30 17:49

papinianus

総合スコア12705

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問