闭包的讲解与简单实用(重新理解)

Posted liveoutfun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闭包的讲解与简单实用(重新理解)相关的知识,希望对你有一定的参考价值。

//闭包的概念就是函数嵌套函数  内部函数可以调用外部函数的参数和变量 并且变量贮存在内存中 不会被垃圾回收机制销毁
//可以手动销毁
//下面介绍闭包的介绍和简单使用

//简单写法
function outer(){ var num=0; function inner(){ num++; return num; }
return inner; } var num=outer(); alert(num());//1 alert(num());//2 alert(num());//3 num=null;//手动销毁


//稍微复杂的写法
var outer=(function(){

var num=0;
return function(){

num++;
return num;

}

})();

       alert(outer());//1
       alert(outer());//2
       alert(outer());//3

//为什么会产生闭包这种情况呢
//首先num被创建在外部函数内部 而且有内部函数对它的引用 所以当函数自执行以后
//num不会被销毁 还是会在内存中
//以上说法不能很好理解闭包这个东西
//下面这些话才可以更好的理解
//就是return 返回的不仅仅是函数 还把函数的所能访问的作用域链(从内到外一直到window)打包返回了
//所以你继续调用还可以访问的到
//总结一句话:函数的作用域取决于被定义时,而不是调用时


/

闭包的好处:
1.希望一个变量长期驻扎在内存当中
2.避免全局变量的污染
3.私有成员的存在


//用法
1.模块化代码
2.在循环中直接找到对应元素的索引

 

1. var test=(function(){

          function init(){alert("游戏加载成功!");}

          function start(){alert("开始游戏!");}

          return {

                  init:init,

                  start:start              

              };

 

      })();

 

    test.init();

    test.start();

   /*

         这样的好处不言而喻

         首先除了test以外的任何对象都访问不到 init 和start 方法

         体现了高内聚的特点

         维护也好

         还可以改成惰性的

    */

 

   2.<ul id="test">

         <li>1</li>

         <li>2</li>

         <li>3</li>

         <li>4</li>

     </ul>

   var getUL=document.getElementById("test");

   var allLi=getUI.children;

   var len=allLi.length;

   for(var i=0;i<len;i++){

       allLi[i].onclick=function(){

            console.log(i);

        }

   }

 

//点击所有的都会是3

因为for循环完毕以后 allLi的点击事件还没有执行  当执行的时候 i已经变成3了 

所以当你触发事件的时候 只会输出3

 

解决方法 :闭包

 

 


   for(var i=0;i<len;i++){

     (function(n){

      

          allLi[n].onclick=function(){


              console.log(n);

          }

    })(i);

    

   }

 

   //当每次for循环的时候 都会自执行匿名函数  并且把当前索引值传进去

     当你触发事件的时候  会访问到你之前传进来的参数n 也就是当时for循环的索引值

     

   //下面这种写法也可以

   


         

  for(var i=0;i<len;i++){

          allLi[n].onclick=(function(n){


                 return function(){

                     console.log(n);

                  }

          })(i);

   }

   //同理 目的就是当每次循环的时候 把 i 保存在事件函数所能访问的最近的作用域中

     就是一个当时执行i的副本  保存在作用域中 来用

 

 

 

   

 
 

 

以上是关于闭包的讲解与简单实用(重新理解)的主要内容,如果未能解决你的问题,请参考以下文章

轻松理解python中的闭包和装饰器 (下)

Spark闭包与序列化

重新理解闭包

30 段 Python 实用代码

重新理解js的执行环境和闭包

即学即用的 30 段 Python 实用代码