- ベストアンサー
セットインターバルの参照とスコープの問題
- 他の関数内にあるsetIntervalを参照する方法はありますか?
- clearInterval(timer0)が他の関数内で使えないエラーになってしまいます。
- スコープの問題に悩んでいます。どのように対処すればいいですか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
> それでは > https://codepen.io/anon/pen/XRKjYY > のように、stop、start二つあって、同じsetTimeoutを片方が関数を呼び出して、片方が引数として変数を実行したい時はどのように対処しますか? まず ========== let iterative = ()=> { iterative = setTimeout(myChange , 5000); } ========== let iterative で変数を定義して無名関数を入れていますが、その関数内でも iterative = で 同名の変数に setTimeout の戻り値を入れようとしているのは間違いですから変数名を分けましょう。 そして setTimeout の戻り値を入れる変数をグローバル変数として定義すれば動きます。 ==================== var it; let iterative = ()=> { it = setTimeout(myChange , 5000); } const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); }); const playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', ()=> { iterative(); }); ==================== もっとプログラミングの基礎的部分から勉強した方がいいと思いますよ。
その他の回答 (2)
- bya00417
- ベストアンサー率33% (58/171)
> 別スコープでの再宣言ですと別の変数となってしまうので、始めに宣言したitを参照できても結局だめですが、再代入にすると別スコープでも同じ変数として中にを変更してしかも別スコープからアクセスできるという事でしょうか? let で宣言した変数はブロックスコープなのでプログラム内の { から } の間でしか参照されません。 しかも { ~ } の間に { ~ } があると、外の [ ~ } 内で let で作られた変数と内側の { ~ } 内で let で作られた変数は別モノ扱いになり、例え同じ変数名でも別々の値が保持されることになります。 ブロックを跨いで値の受け渡しをしたい場合は、グローバルスコープの減数を使うか、関数スコープの変数を使うしかありません。 JavaScript は何も宣言せずに変数を使うとグローバルスコープ扱いされ、よく考えずに作られたプログラムだと変数名がダブることで意図しない動作を引き起こしてしまうためグローバルスコープを極端に嫌って絶対使うなと言うような言い方をする人もいますが、時と場合によってはグローバルスコープを使わないといけない場合もあるので、ちゃんと意識して使い分けすればいいのです。 > としてもitの中身がundefinedになってしまいます。 どういう使い方をされているのでしょう? 例示されているプログラムだけで動かせば問題無い事を確認しています。 例示された範囲外に何が書かれているのか分からないので、ほかに書かれているプログラムの影響まで考慮した回答はできませんよ。
お礼
setTimeout(myChange , 5000); var it; let iterative = ()=> { it = setTimeout(myChange , 5000); } const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); }); const playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', ()=> { iterative(); }); } となっていたので恐らく始めのsettimeoutが止まっていなかったのだと思います。 2つある2番目だけが止まって1番めが止まっていなかったので止まらなかったという事で 良いでしょうか? よって下記のように変更したのですがおかげさまで停止ボタンでの停止には成功しました。 しかし今度はその後の再生ボタンがうまくいきません 一度止めてから再度再生を押しても再生が再開されません。 何度も恐縮ですが理由がわかりますか? var it; let iterative = ()=> { it = setTimeout(myChange , 5000); } iterative(); let stoppingNow; const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); let stoppingNow = true; }); const playBtn = document.getElementById('js-play-btn'); if(stoppingNow === true) { playBtn.addEventListener('click', ()=> { iterative(); stoppingNow = false; });
- bya00417
- ベストアンサー率33% (58/171)
timer0 の定義を関数の外に出してグローバル変数にするだけでいいんじゃないでしょうか。 ==================== var timer0; let startSlot = (()=> { timer0 = setInterval(() => { 内容 }, interval); })(); // stopSlot let stopSlot = (()=> { const stop0 = document.getElementById('stop0'); const stop1 = document.getElementById('stop1'); stop0.addEventListener('click', ()=> { clearInterval(timer0); }); })(); ====================
お礼
ありがとうございます。 そうかもしれないですね。 それでは https://codepen.io/anon/pen/XRKjYY のように、stop、start二つあって、同じsetTimeoutを片方が関数を呼び出して、片方が引数として変数を実行したい時はどのように対処しますか?
お礼
別スコープでの再宣言ですと別の変数となってしまうので、始めに宣言したitを参照できても結局だめですが、再代入にすると別スコープでも同じ変数として中にを変更してしかも別スコープからアクセスできるという事でしょうか? ただ var it; let iterative = ()=> { it = setTimeout(myChange , 5000); } const pauseBtn = document.getElementById('js-pause-btn'); pauseBtn.addEventListener('click', ()=> { clearTimeout(it); }); const playBtn = document.getElementById('js-play-btn'); playBtn.addEventListener('click', ()=> { iterative(); }); } としてもitの中身がundefinedになってしまいます。