Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

for文の宣言について

解決したいこと

forを用いたときのスコープについて教えて欲しいです。
解決方法が分かったのですが、いまいち納得がいかず、、、

for(i=0;をfor(let i=0;にしてスコープを縛るとこまではわかりました

しかし、スコープ外でデバッグすると、iが2で返されてしまいます。
どこかで再代入されているならまだしも、
2なんか入れた覚えはないぞ、、というところで
なぜそうなるかを教えていただけたら幸いです

該当するソースコード


<label><input type="checkbox" name="group" value="大谷" checked>大谷</label>
<label><input type="checkbox" name="group" value="藤浪">藤浪</label>

<ul id="setValue">
<ul>

let array = [];
let obj = {};

let group = document.getElementsByName("group");
let setValue = document.getElementById("setValue");

let li = document.createElement('li');

for(i=0;i<group.length;i++){
	console.log(i) //結果 0 ,1,2

    group[i].addEventListener("click",function(e){
        console.log(i) //結果2
      	array = [];
    
        for(j=0;j<group.length;j++){
        	console.log(i) //結果 2 2 2
    		group[j].checked = false
        }
        console.log(i) 
        e.checked = true;
    
        if(group[i].checked){
       		console.log(i) //結果エラー
            setValue.appendChild(li)    
        }
	})
    console.log(i) // 結果 0.1.2
}
console.log(i) // 結果2

自分で試したこと

for内にletを宣言すれば、とりあえずここの問題は解決しましたが
なぜそうなるかの理由を調べてもわからず、、

console.log()で各スコープをデバッグした結果をコメントアウト致しましたので、、よろしくお願いします

*このソースコードはまだ完成はしていません。スコープの悩みだけでも解決できればと思い

1

2Answer

上の例では即時関数で対応してます?
addEventListenerの悪戯?と考えてみては?

 addEventListenerは非同期関数を作成した時点ではローカルスコープの変数iならfor文のiの値がセットされています。
 しかし、広域スコープのiの場合はclickされてバラバラに動き始めた時点、の最新のiの値が参照されます。

p.s. let ではなく var はNGであること?ついでに教えて下さい。(varは古い仕様)

1Like

Comments

  1. @gucho-n

    Questioner

    ご回答ありがとうございます。
    スコープに関しては関数内の変数が、関数外で呼ばれた時の挙動の変化があることは気にしておりましたが、イベントの中でループし切った値が使われていることは盲点でした。

let宣言しない場合、グローバル変数に代入されます。
グローバル変数はどこからでも参照できる変数で、残り続けます。

for(i=0;i<group.length;i++){i0 から group.length まで変化して、最終的に i には group.length が代入されてループ終了します。
group.length の値が 2 で、letを付けなかったときの値が残っていると考えられます。

1Like

Comments

  1. @gucho-n

    Questioner

    ご回答いただきありがとうございます。
    私は今までイベントが発火する前後関わらず、iのループは昇順に反映されているものだと思っていたので、まさかループが終了した後のiが代入されているとは思いませんでした。

Your answer might help someone💌