0

次のコードがあります。Javascript do while、setTimeout、イベント変数スコープ

document.getElementById("whatever").addEventListener("click", function(e){ 

    var target = e.target; 
    var search = "TR"; 
    do{ 
     if(target.nodeName.toUpperCase() === search) { 
      window.setTimeout(function(){ 
       console.log(target); 
      }); 

    }while(target = target.parentNode); 
}); 

私は、変数ターゲットはwindow.setTimeoutはの外側のスコープ内にあるため、という印象の下にあった、とのonclickイベントリスナークロージャ内で、それはsetTimeoutメソッドのスコープに利用できるだろうが、明らかにそれはありますそうではありません。どうしてこれなの?正確にここで何が起こっているのですか?

私は

window.setTimeout(function(){ 
       console.log(this); 
      }.bind(target); 

、私はこれを行うことによって設定されたタイムアウト匿名関数にコンテキストを渡すことができます知っているが、私は、ターゲットが一部として設定されたタイムアウト匿名関数に利用できないでしょう理由として損失にとどまっていますイベントリスナクロージャの

閉鎖の仕組みの誤解に対する返答とお詫びについては、事前にお礼を申し上げます。

+0

変数*はスコープ内にあります。しかし、あなたがアクセスした時点で、すでにヌルになるまでそれを繰り返していました。 – Bergi

答えて

1

変数はコールバック内で使用できます。

ただし、コールバックが実行されるまでに、変数はヌルです(whileループが終了しているため)。

+0

私は、クロージャーでは、変数がクロージャ作成の瞬間に保存された状態でメモリ内の特別な場所にコピーされていたという印象を受けました。 setTimeoutコールバックは、イベントリスナーコールバックとは別に独自のクロージャを作成しませんか?申し訳ありませんが、私はそのコンセプトを誤解しています。 –

+2

@LorenShqipognja:いいえ。 closureはoriginal_変数をクローズし、常に現在の値を反映します。コピーはありません。 – SLaks

+0

'target'変数自体が閉じられます。関数が作成された時点での値はそうではありません。 – Quentin