1. 程式人生 > >我所認識的閉包

我所認識的閉包

(~ ̄(OO) ̄)ブ,閉包,一個面試長問的問題,本白也迷糊了很久。慢慢不斷地有了自己的一點認識,這裡分享一下~~~
廢話不多說,先看題:


var output = (function () {
    var x = y = 7;
    return [
        function () {
            console.log(x)
        },
        function () {
            console.log(y);
        }
    ]
})();
for (var i = 0; i < 2; i++) {
    output[i]();
}
console.log(++y);
console.log(++x);

結果是什麼呢???
大家可以先自己想一下,然後來聽我分析(xiache)(#^.^#);
首先我們從for迴圈開始看起,迴圈了2次,分別執行了outputp[0]();outputp[1]();
首先outputp會執行return出一個數組,陣列中有兩個方法,所以outputp[0]();outputp[1]();會執行陣列中的兩個方法。

  • 這裡就涉及到閉包的知識點了~~~

第一次聽到閉包,別人給我的解釋就是,函式中輸出函式。
哈哈,簡單粗暴的理解,不過也對,這樣確實是形成了閉包。關於閉包,我們就要說到javascript的作用域,我們都知道,js中無非就是全域性變數和區域性變數。在js中,函式的內部都可以訪問的全域性變數的值,但在函式外部無法獲取內部的值。但有一個方法可以幫我們在外部調取內部的值,沒錯,這就是閉包~~~
我們先繼續看這道題,我將一步步解釋。
這個是函式內部return函式,形成了閉包。所以我們在外部可以獲取到 x,y的值。沒錯也就是我們可以用outputp[0]();outputp[1]();來獲取,也就是會列印 7 7;

  • 為什麼可以

一般的函式,沒有return的時候,函式執行完成後也就會關閉了,但閉包會return出來一個函式,所以這個函式不能關閉,所以我們可以利用這個特性,這也就是我所認為的閉包。(萌新,否求指);

  • 繼續看

最後的兩行console.log(++y);console.log(++x); 這裡我們回到 var x = y = 7;
等用於 y = 7;var x = y; 所以,y其實是個全域性變數。而x是區域性變數。
console.log(++y) 會輸出8 因為全域性變數在哪都可以訪問到
console.log(++x) 會報錯 Uncaught ReferenceError: x is not defined
有的同學可能要問,既然閉包 也就是x的值還在記憶體中,為什麼訪問不到呢,因為我們之前說過,函式外部無法獲取內部的值,所以直接呼叫x是獲取不到的,閉包是利用outputp[0]()這種return出的函式呼叫其父的值x,y才獲取的到。

  • 思考

閉包有什麼用呢,本萌新在實戰中也用到過幾次,但畢竟經驗不足。這裡就說兩點吧。


for(var i = 0; i < 8;i++) {
    setTimeout(function(){
          console.log(i)
     },500) 
}

這個會輸出 8 個 8,面試題考爛了的。 如何輸出0/1/2/3/4/5/6/7呢
只要將var i 變成 let i 就可以了。 如果不用es6語法怎麼做呢? 這樣:


for (var i = 0; i < 8; i++) { 
  (function(i){  
    setTimeout(function (){
      console.log(i); 
     },1000); 
  })(i); 
}

這個也是利用閉包的原理,函式內部可以看父親函式的值,因為父函式中有子函式,所以每次for迴圈i的值都在記憶體中,沒有變。

第二點就是利用閉包的特點,增加某些key的安全性。 比如有一個很重要的資訊 “樓主可真是個小機靈鬼”,在一個函式內部,我們在外部想到用它,但不想任何人都可以隨便調到,因為這個資訊很重要。這樣我們就可以這樣:


function getKey(){
    var key = "樓主可真是個小機靈鬼";
    return {
         _xxx : (function(){
           return key;
        })()
    }
};
console.log(getKey()._xxx)

key我們想自己全域性的呼叫,但不想讓同事呼叫。_xxx可以是一個加密的字串,我就可以這樣寫這樣我全域性的都可以用到。
這就是本小白對閉包的理解,否佬指(不對的地方,麻煩大佬指出);
最後祝大家身體健康,謝謝~~~

原文地址:https://segmentfault.com/a/1190000016750915