javascript 闭包及其解决

Posted coding500HHY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript 闭包及其解决相关的知识,希望对你有一定的参考价值。

闭包

是指在一个函数中声明一个函数,在外部函数结束的时候返回内部函数的引用,那么在执行外部函数的时候就会

产生一个内部函数的引用,因为外部函数执行完成,理论上外部函数的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 闭包及其解决的主要内容,如果未能解决你的问题,请参考以下文章

深入浅出Javascript闭包

JS---闭包

javascript解决闭包漏洞的一个问题

javascript解决闭包漏洞的一个问题

JavaScript 闭包详解

Javascript闭包