1. 程式人生 > >javascript 閉包及其解決

javascript 閉包及其解決

script 應該 ++ 內部函數 其中 存儲 分享 TE 保存

閉包

是指在一個函數中聲明一個函數,在外部函數結束的時候返回內部函數的引用,那麽在執行外部函數的時候就會

產生一個內部函數的引用,因為外部函數執行完成,理論上外部函數的ao的引用是應該被刪除或者說釋放的。

但因為有了內部函數的引用,這個內部函數在聲明的時候就已經指向了外部函數的ao以及go,所以,即使外部函數

ao的引用已經釋放,由於內部函數被保存在了外部,導致外部函數申明與執行所產生的ao被保留下來。

<body>
  <script type="text/javascript">
    function a(){
      function b(){
        
var bbb = 234;         consloet.log(aaa);       };
        var a = 123         
return b;     }     var golb = 100;     var demo = a();     demo(); </script> </body>

此例的輸出結果是:123

按原來的理解,b函數中是沒有a這個變量的,正常如果沒有外部的a函數,就會報錯 a is not define

但是這裏,由於在a執行完的時候,把b的引用保存在了函數a之外,而b這個函數在聲明的時候,它的scope chain仍然和a執行是同一個,

即:0:aAO;1:GO,就是把a中的執行上下文保存在了b函數中。在執行函數b的時候回生成一個bAO放在scope chain的0位置,執行完的

時候刪除這個bAO,而在1、2位置的0:aAO;1:GO被永久的保留了下來。

aAO中是由a = 123這個變量的,故而最終的結果是打印出a的值!~

這 就是閉包!

**註意點**------當內部函數被保存到外部時,將會生成閉包。閉包會導致原有scope chain(作用域鏈)不釋放,造成內存泄漏

      內存泄漏:由於內存一直占用,導致可用內存空間減小,感覺就像內存泄漏了一樣,就叫內存泄漏了~~!會導致加載非常慢!!

scope chain 中的沒生成一個新的ao,必然繼承外部函數產生的ao與go,這裏的繼承是指指向了原來那個AO、GO,而不是生成一個一模一樣的

ex:

<body>
  <script type="text/javascript">
    function text(){
      var num = 100;
                  function b(){
                       num ++;
                       console.log(num);    
                  }
                 function b(){
                      num --;
                      console.log(num);
                 }
                  return [a,b];
    }
    var myArr = text();
    myArr[0]();
    myArr[1]();
</script>
</body>                                                       

輸出的結果是:101 100

而不是101 99,註意其中的區別!

  所以再修改來自外部函數的ao時,是修改的同一個AO

ex:

<body>
  <script type="text/javascript">
    function a(){
      var num = 100;
                  function b(){
                       num ++;
                       console.log(num);    
                  }
                  return b;
    }
    var demo = a();
    demo();
    demo();
</script>
</body>                        

此例的結果是:101

       102

有累加的效果

閉包的作用:1實現共有變量----->函數累加器

2可以做緩存(存儲結構)----->eater

      3可以實現封裝,屬性私有化------>Person();

      4模塊化開發,防止汙染全局變量

ex: 實現共有變量----->函數累加器

<body>
  <script type="text/javascript">
    function add(){
            var count = 0;
                        function demo(){
        count ++;
        consloet.log(count);
      };
     
        return demo;
    }
    var counter = add();
    
    counter();
            counter();   
            counter();   
            counter();   
            counter();   
            counter();   
            counter();   
            counter();   
</script>
</body>                

輸出結果: 1 2 3 4 5 6 7

ex:可以做緩存(存儲結構)----->eater   3

<body>
  <script type="text/javascript">
    function eater(){
      var food = "";
                  var obj = {
                        eat : function(){
                        console.log("i am eating!" + food);
                        food = "";
                        },
                        push : function(myfood){
                                food = myfood;
                        }
                  }
                  return obj;
              }
      var demo = a();
      erter1.push(‘banana‘);
      eater1.eat();
</script>
</body>         

輸出結果; i am eating banana

其中實際有兩個過程,一個把banana放入myfood,第二個過程才是打印 i am eating banana

技術分享圖片

javascript 閉包及其解決