71312
for文を使用する時、変数の名前を動的に変更したいです。  
下記のように、sliderをslider[i]と書いてみましたが、  
この場合、javascriptがうまく作動しません。  
slider0,slider1のように別の変数として扱われるようにしたいです。  
下のjavascriptの記述は省略して書いていますので、参考程度にしてください。  
（console.log(slider[i]);で確認したところ、中身は入っているようです。）

```

    $(function() {
        var slider = {};
        var thumbnailItem = {};
        var classLength = $(".slide-box").length;
    
        for (var i = 0; classLength > i; i++) {
            newClassMain = "main" + i;
            newClassThumbnail = "thumbnail" + i;
            slider[i] = "." + newClassMain;
            thumbnailItem[i] = "." + newClassThumbnail + " " + "li";
    
            $(slider[i]).on("init", function(slick) {
            var index = $(".slide-item.slick-slide.slick-current").attr(
              "data-slick-index"
            );
            $(thumbnailItem[i] + '[data-index="' + index + '"]').addClass(
              "thumbnail-current"
            );
    
            console.log(slider[i]); //.main0 .main1 とclassLengthの数だけ返します。
        }
        console.log(slider[i]); //forの外なのでundefineがでます。
    }
    
```

こちらを参考にしております。  
<https://teratail.com/questions/68851>  
evalの使い方も今一つつかめていません。  
説明が下手ですみません。ご教示よろしくお願い申し上げます。

### 【追記】やりたいこと

別の質問ページ<https://teratail.com/questions/298665>の内容になるのですが、  
slickスライドで  
スライドとサムネイルのクラス名が同じだと、  
複数増やした状態で、サムネイルをクリックしたら、同時にスライドが動いてしまうことに気付きました。。。  
なので、スライドとサムネイルのクラス名を変更する方法で実装を考え直しています。

そこで、javascriptの記述をスライダーの数だけ複製し、  
スライダーとサムネイル画像の部分を、  
下記のように、変数と中に入れるクラス名を手動で変更したら、うまく起動しました。

```

        var slider = ".main0"; //スライダー
        var thumbnailItem = ".slide-thumbnail0 li"; //サムネイル画像
    
```

```

        var slider1 = ".main1"; //スライダー
        var thumbnailItem1 = ".slide-thumbnail1 li"; //サムネイル画像
    
```

これをfor文を使って動的に変数とクラスの番号を変更したいのですが、うまくいきません。。。  
下記のように、クラスの番号を動的に変更するようにしたのですが、  
スライドが複数ある場合、  
どのサムネイルをクリックしても、一番下のスライドが反応してしまいます。

```

      $(function() {
        // slide（サムネイルつき）---------------------
        // 参考サイト：https://takblog.site/web/?p=144
    
        //【追加】スライドの数を数え、その数だけ個別のクラスを付与する
        var classLength = $(".slide-box").length;
        var newClassMain, newClassThumbnail, slider, thumbnailItem;
        //【追加】サムネイル画像アイテムに data-index　でindex番号を付与
        for (var i = 0; classLength > i; i++) {
          newClassMain = "main" + i;
          newClassThumbnail = "thumbnail" + i;
          slider = "." + newClassMain;
          thumbnailItem = "." + newClassThumbnail + " " + "li";
          $(".slide-main")
            .eq(i)
            .addClass(newClassMain);
          $(".slide-thumbnail")
            .eq(i)
            .addClass(newClassThumbnail);
          //サムネイル画像アイテムに data-index　でindex番号を付与
          $(thumbnailItem).each(function() {
            var index = $(thumbnailItem).index(this);
            $(this).attr("data-index", index);
          });
          //スライダー初期化後、カレントのサムネイル画像にクラス「thumbnail-current」を付ける
          //「slickスライダー作成」の前にこの記述は書いてください。
          $(slider).on("init", function(slick) {
            var index = $(".slide-item.slick-slide.slick-current").attr(
              "data-slick-index"
            );
            $(thumbnailItem + '[data-index="' + index + '"]').addClass(
              "thumbnail-current"
            );
          });
          //slickスライダー初期化
          $(slider).slick({
            arrows: true,
            dots: true,
            fade: true,
            infinite: false //これは必須
          });
          //サムネイル画像アイテムをクリックした時にスライダー切り替え
          $(thumbnailItem).on("click", function() {
            var index = $(this).attr("data-index");
            $(slider).slick("slickGoTo", index, false);
          });
          //サムネイル画像のカレントを切り替え
          $(slider).on("beforeChange", function(
            event,
            slick,
            currentSlide,
            nextSlide
          ) {
            $(thumbnailItem).each(function() {
              $(this).removeClass("thumbnail-current");
            });
            $(thumbnailItem + '[data-index="' + nextSlide + '"]').addClass(
              "thumbnail-current"
            );
          });
        }
      }
    
```

htmlの記述はこうなります。htmlはこのまま複製しても使えるようにしたいです。

```

    <!--1つのスライド-->
    <div class="slide-box">
      <!--メインスライド-->
      <ul class="slide-main">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
      </ul>
      <!--/メインスライド-->
      <!--サムネイルスライド-->
      <ul class="slide-thumbnail">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
      </ul>
      <!--/サムネイルスライド-->
    </div>
    <!--/1つのスライド-->
    
```

以上を試してみて、変数名も変更する必要があると考えています。  
しかし、slider[i],thumbnailItem[i] ではうまくいきませんでした。。

長文で申し訳ありません。  
どうかお力をお借りできれば嬉しいです。  
よろしくお願い申し上げます。
CC BY-SA 4.0
2020-10-18T10:01:09.633
71304
2020-10-19T02:33:42.737
2020-10-19T02:30:21.047
42357
42357
question
javascript jquery
for文を使用する時、変数の名前を動的に変更したい。
ループでコールバック関数を作るとループ変数の値ではなくて変数自体がキャプチャされるので、コールバックが呼ばれるタイミングでの変数の値が使われます。質問のようなイベントハンドラの場合、ループ終了後なのでループ変数はループ終了時の値(質問の例だと`i
== classLength`)になります。

```

    for (var i = 0; i < 10; i++) {
      setTimeout(()=>console.log(i), 10);
    }
    
```

対策としては例えば次のような方法があります。

ES6以降が使える場合は、`let`でスコープをループ内のブロックに限定する。

```

    for (var i = 0; i < 10; i++) {
      let j = i;
      setTimeout(()=>console.log(j), 10);
    }
    
```

または

```

    for (let i = 0; i < 10; i++) {
      setTimeout(()=>console.log(i), 10);
    }
    
```

ES5までの環境では無名関数を使う。

```

    for (var i = 0; i < 10; i++) {
      (function(j) {
        setTimeout(()=>console.log(j), 10);
      })(i);
    }
    
```
CC BY-SA 4.0
2020-10-19T02:32:25.977
71312
2020-10-19T02:32:25.977
241
71304
answer
**解決方法**  
別の質問ページで解決しました。<https://teratail.com/questions/298792>

**for内に書いているiをvar → letに変更** し、  
**slider → slider[i],  
thumbnailItem → thumbnailItem[i]**  
に書き直したら、  
htmlのスライド・サムネイル部分を複製しても、  
各スライドとサムネイルどうしで連動するようになりました！

解決したjavascriptの記述を下に書いておきます。

```

    $(function() {
        // slide（サムネイルつき）---------------------
        // 参考サイト：https://takblog.site/web/?p=144
    
        // スライドの数を数え、その数だけ個別のクラスを付与する
        var classLength = $(".slide-box").length;
        var newClassMain, newClassThumbnail;
        var slider = {};
        var thumbnailItem = {};
        // サムネイル画像アイテムに data-index　でindex番号を付与
        for (let i = 0; classLength > i; i++) {
          newClassMain = "main" + i;
          newClassThumbnail = "thumbnail" + i;
          slider[i] = "." + newClassMain;
          thumbnailItem[i] = "." + newClassThumbnail + " " + "li";
          $(".slide-main")
            .eq(i)
            .addClass(newClassMain);
          $(".slide-thumbnail")
            .eq(i)
            .addClass(newClassThumbnail);
          //サムネイル画像アイテムに data-index　でindex番号を付与
          $(thumbnailItem[i]).each(function() {
            var index = $(thumbnailItem[i]).index(this);
            $(this).attr("data-index", index);
          });
          //スライダー初期化後、カレントのサムネイル画像にクラス「thumbnail-current」を付ける
          //「slickスライダー作成」の前にこの記述は書いてください。
          $(slider[i]).on("init", function(slick) {
            var index = $(".slide-item.slick-slide.slick-current").attr(
              "data-slick-index"
            );
            $(thumbnailItem[i] + '[data-index="' + index + '"]').addClass(
              "thumbnail-current"
            );
          });
          //slickスライダー初期化
          $(slider[i]).slick({
            arrows: true,
            dots: true,
            fade: true,
            infinite: false //これは必須
          });
          //サムネイル画像アイテムをクリックした時にスライダー切り替え
          $(thumbnailItem[i]).on("click", function() {
            var index = $(this).attr("data-index");
            $(slider[i]).slick("slickGoTo", index, false);
          });
          //サムネイル画像のカレントを切り替え
          $(slider[i]).on("beforeChange", function(
            event,
            slick,
            currentSlide,
            nextSlide
          ) {
            $(thumbnailItem[i]).each(function() {
              $(this).removeClass("thumbnail-current");
            });
            $(thumbnailItem[i] + '[data-index="' + nextSlide + '"]').addClass(
              "thumbnail-current"
            );
          });
        }
    }
    
```

関数スコープやletの意味がよくわかっていなかったので、  
この機会に学ぶことができました。  
参考にしたサイト様も載せておきます。  
＜関数スコープ＞  
・[JavaScript中級者への道【3.
関数スコープ】](https://qiita.com/matsuby/items/1010ae38ee6258fd8020)  
＜var,letについて＞  
・[JavaScriptで書く「var,let,const」の違いと使い分け方法](https://techacademy.jp/magazine/14872)  
・[letリファレンス](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/let)

本当にありがとうございました！！！
CC BY-SA 4.0
2020-10-19T02:33:42.737
71313
2020-10-19T02:33:42.737
42357
71304
answer