あなたはJSシリーズ(15)を知らない - サイクリングとクロージャ

クロージャを説明するために、共通例えばループであります
ためVAR I = 1; I <= 5; I ++ ){ 
  のsetTimeout(関数タイマー(){ 
    にconsole.log(I); 
  }、 0 
}

遅延コールバック関数は、ループの実行、変数の値は6となっているときに、サイクルの終わりまで実行されるため、各時間が出力6であろう。私たちは、実行時のキャプチャでのループの各反復は、自分自身に私のコピーを与えると信じています。しかし、原則的範囲によると、呼び出しは同じIです。これは、一つだけ私を持っています。遅延関数がコールバックがサイクルを使用することなく、5回繰り返した定義されている場合、同じコードは以下と等価です

VAR iは1 = 
setTimeout(関数タイマー(){ 
  にconsole.log(I); 
}、 0 
iは 2 = 
setTimeout(関数タイマー(){ 
  にconsole.log(I); 
} 0 )、
iが 3 = 
setTimeout(関数タイマー(){ 
  にconsole.log(I); 
}、 0 
iは 4 = 
setTimeout(関数タイマー(){ 
  にconsole.log(I); 
} 0 )、
iが 5 = 
setTimeoutメソッド(関数タイマー(){ 
  にconsole.log(I)。
}、 0 
iは 6 =。

6出力の5倍。私たちは、より多くのスコープの閉鎖は、iのそれぞれへの参照を保持している必要があります



ためVAR I 1 =; I <= 5; I ++ ){ 
  (関数(){ 
    のsetTimeout(関数タイマー(){ 
      にconsole.log(I); 
    }、 0 
  })()
}

これは、スコープの層が追加されますが、スコープは、それは空だった、それは独自の変数を必要とし、iの値を格納するために使用します

ためVAR I = 1; I <= 5; I ++ ){ 
  (関数(){
    VARの J = I; 
    のsetTimeout(
関数タイマー(){       にconsole.log(J);     }、 0   })() }

ライン、それができ通常の作業。私たちは、このコードにいくつかの改良を行うことができます。

 

ためVAR I 1 =; I <= 5; I ++ ){ 
  (関数(J){ 
    のsetTimeout(関数タイマー(){ 
      にconsole.log(J); 
    }、 0 
  })(I)
}

各繰り返しは、新しいスコープがそのようにコールバック関数は、内部変数へのアクセスを所有している遅延する生成します。言い換えれば、我々はすべての必要性、各反復ブロックスコープ、ブロックスコープをハイジャックするために使用することができましょう。基本的にブロックスコープの範囲に変換され、閉じることができ、

 

以下のために(iは1 =せ; I <= 5; iが++ ){ 
  せJ = I。
  setTimeout(関数タイマー(){ 
    にconsole.log(J); 
  }、 0 
}

多層スコープ効果を有するそのような閉鎖は同じです。しかし、let文のためのループの頭部は特別な振る舞いを持つことになり、変数はループ内でより順次よりも宣言されているように、この動作は、各繰り返し文。

 

以下のために(iは1 =せ; I <= 5; I ++ ){ 
  のsetTimeout(関数タイマー(){ 
    にconsole.log(I)を
  }、 0 
}
クール、ブロックスコープとクロージャ一緒には無敵することができます
 

 

おすすめ

転載: www.cnblogs.com/wzndkj/p/12364998.html