【フロントエンドエンジニアマニュアル】JavaScriptの閉鎖


閉包は確かに腐ったという概念です.学校招社の募集は問われます.今日はまとめます.まず定義しておきます.クローズドは関数とその関数の語法のスコープの組み合わせです.この定義は教条を比較するもので、クローズドは関数として理解でき、またこの関数はその内部で宣言されておらず、そのパラメータではない変数を使用しています.くりを一つあげる
function foo() { 
    var a = 2;
    function bar() { 
        console.log( a );
    }
    return bar; 
}
var baz = foo();
baz(); // 2
通常の通り、foo関数は実行後に内部の変数aを破壊しますが、bar関数の内部はaに対する参照を保持していますので、foo()を呼び出してbazに参照を付与しました.baz()を実行してもaをプリントできます.この栗の中で、関数バーと変数aに対する引用は閉じられています.
閉包とスコープ
クローズドとスコープの関係については、クローズドは実はスコープの延長であると理解しています.JavaScriptでは関数の外部変数が関数の内部で使用できますので、いつの間にかクローズドが発生します.上のコードの断片では関数の外部変数を内部で使用することができません.
クローズドは何に使いますか?
プライベート変数とプライベートメソッドのシミュレーション
var Dog = (function(){
    var privateVal = 'dog'
    function doing(val) {
        console.log(privateVal + ' ' + val)
    }

    return {
        run: function(){
            doing('run')
        },
        bark: function(){
            doing('bark')
        }
    }
})()

Dog.run()    // dog run
Dog.bark()   //  dog bark
見ることができるのは、runとbarkの二つのクローズドが同じ語法のスコープを共有し、プライベートメソッドdongを参照していることです.このようにして、私達は外に向かってrunとbarkの2つの共通インターフェースだけを暴露してプライベートな変数と方法を隠すことができます.
クローズドとループ
面接で一番多くの問題があるかもしれません.
for(var i = 1;i <= 5;i++) {
    setTimeout(function() {
        console.log(i)
    }, i*1000)
}
//         6,   5 
なぜ、私たちが思っている順番に1秒間隔で1、2、3、4、5をプリントアウトしないですか?まず、このサイクルは5つのクローズドを生み、そして最も重要なのは、この5つのクローズドは同じ作用領域にあります.つまり、それらは同じiを参照しています.forループが終了すると、iは6になります.したがって、5つの匿名関数が実行されると、その同一のiが順次印刷されますので、5つの6つが印刷されます.どう解決しますか?前にも言ったように、この5つのクローズドを異なる役割領域にし、それぞれの役割領域においてそれぞれのiを持たせても良いです.自己実行関数を使って新しいスコープを作成できます.
for(var i = 1;i <= 5;i++) {
    (function(k){
        setTimeout(function() {
        console.log(k)
    }, k*1000)
    })(i)
}
このコードセグメントでは、各setTimeoutは独立した作用領域にあり、それぞれのkを参照しており、外層作用領域のiを指しているわけではないので、1、2、3、4、5もletを使用することができる.
for(let i = 1;i <= 5;i++) {
    setTimeout(function() {
        console.log(i)
    }, i*1000)
}
for循環ヘッダのletは、forサイクルのブロックにiを結びつけるだけでなく、実際にはサイクルの各反復に再結合され、前のサイクル反復終了時の値を使用して再割当されることを保証する.実はletを使う本質は
for(let i = 1;i <= 5;i++) {
    let i =        i
    setTimeout(function() {
        console.log(i)
    }, i*1000)
}
実は闭包はこのように多くのもので、しかも主に作用域の概念で、作用域は分かりました.that's all,thank you.
参考資料はJavaScriptシリーズ-クローズドMDN-クローズド「知らないJavaScript-上巻」「毎日一題」JSのクローズドは何ですか?