JavaScript-クローズド(面接問題から)


まずコードを見て、自分の答えを出します.
    for(var i=0;i<5;i++){
        setTimeout(function(){
            console.log(i);
        },1000)
    }
    
    console.log(i);
めったに出られないです.この問題の答えは5 5 5 5 5 5 5 5 5です.すぐに一つの5を出力して、1秒後に5つの5を出力します.
ここで答えを変えたいなら、5 1 2 3 4 5です.じゃ、閉包を熟知している学生は、すぐにこのような方法を導き出すことができます.
    for(var i=0;i<5;i++){
        (function(j){   //j = i
            setTimeout(function(){
                console.log(j);
            },1000)
        })(i);
    }
    
    console.log(i);
タイマーに詳しいなら、もう一つの方法を使ってもいいです.
    for(var i=0;i<5;i++){
        setTimeout(function(j){
            console.log(j);
        },1000,i)
    }
    
    console.log(i);
ここのsetTimeoutの3番目のパラメータは、現在の実行関数に提供される他のパラメータを示すオプションです.
もちろんES 6の文法を熟知すれば、すぐにvarをletに変えたいです.コードは以下の通りです.
    for(let i=0;i<5;i++){
        setTimeout(function(){
            console.log(i);
        },1000)
    }
    
    console.log(i);
もちろんこの方法は、i値がブロックレベルの作用領域内でのみ有効となるため、エラーが発生します.しかし、この方法は確実にタイマー内で印刷された結果を1 2 3 4 5に変更できます.
クローズドは、簡単に言えば、関数が別の関数の変数にアクセスでき、変数がごみ回収メカニズムによって回収されないようにします.
最も一般的なクローズドとは、関数の内部にサブ関数を追加し、関数の局所変数にサブ関数を介してアクセスすることです.