JavaScript: Understanding the Weird Parts - Understanding Closures - Part 2

7317 ワード

コードを見せてから始めます
function buildFunctions() {
  var arr = [];
  for(var i=0;i<3;i++) {
    arr.push(
      function() {
        console.log(i)
      }
   )
  }
  
  return arr
}

var fs = buildFunctions()
クラシックなモジュールコード
fsに関数を格納する配列
fs[0]()
fs[1]()
fs[2]()
生成された関数の実行
iはどのくらい出ますか?驚くべき部分
ほとんどの推定値:0、1、2
実際のコード:3、3、3
実行スタックを見て
グローバル実行コンテキスト:fs->buildFunctions()
buildFunctions: i -> 3, arr = [f0, f1, f2]砲口の回転に伴いiは0から1、2、3に変化する.
pushは関数式です
つまり、コードは実行されません
buildFunctionsが終了し、実行スタックでポップアップ
関数出力3は、関数呼び出し時にiが3を指す
ちょっとおかしいかもしれませんが、javascriptエンジンの働き方を知るだけでいいです.
関数を実行するときは現在の環境のみ
ES 6 letの場合は?
function buildFunctions() {
  var arr = [];
  for(var i=0;i<3;i++) {
    let j = i
    arr.push(
      function() {
        console.log(j)
      }
   )
  }
  
  return arr
}

var fs = buildFunctions()
letはブロックにスキャンされました
ブロック?かっこ
関数構文から異なるメモリ変数にアクセス
別のソリューションIIFE
function buildFunctions() {
  var arr = [];
  for(var i=0;i<3;i++) {
    let j = i
    arr.push(
      (function(j) {
        return function() {
          console.log(j)
        }
      }(i))
   )
  }
  
  return arr
}

var fs = buildFunctions()
実行コンテキストを個別に作成