闭包的两个作用

163 阅读1分钟

闭包的两个作用

从性能角度讲,我们真实项目中应该减少对闭包的使用(因为闭包会产生不释放的栈内存,过多使用容易导致内存溢出或者降低性能)

  • 保护
  • 保存
  1. jQuery(JQ)前端非常经典的类库:提供了大量的方法供开发人员使用

    =>为了防止全局变量污染(解释:导入JQ后,它里面有大量的方法,如果这些方法不保护起来,用户编写的方法很容易和JQ方法名字相同产生冲突,产生冲突可以理解为全局变量污染),JQ中的方法和变量需要用闭包保护起来

    /*==JQ源码剖析==*/
    (function(global, factory){
        //...
        //typeof window!=="undefined"?window:this 验证当前所处环境的全局对象是window还是global等
        //factory=>function zhufeng(window,noGlobal){}
    	factory(global); //=>zhufeng(window)
    })(window,function zhufeng(window,noGlobal){
        //...
        var jQuery=function(selector, context){
            //...
        };
        
     	//=>通过给全局对象增加属性:jQuery和$,把私有的jQuery方法暴露到全局作用域下,供外面使用(等价于return jQuery)(外界需要使用函数中的私有内容,我们可以基于window.xxx和return xxx两种方式实现这个需求)   
        window.jQuery = window.$ = jQuery;
    });
    
    //=>开始使用JQ
    jQuery(); //=>window.jQuery()
    $();
    

    在真实项目中,我们一般都要把自己写的内容放到一个闭包中,这样可以有效防止自己的代码和别人代码产生冲突(全局变量污染:真实项目中是要尽可能减少对全局变量的使用的);如果需要把自己的东西给别人用,基于return和window.xxx等方式暴露给别人即可

    //=>原生JS
    var zhufeng=(function(){
      //....A自己写的代码  
      return {
         name:'xxx'
      };
    })();
    
    (function(){
      //....B自己写的代码  
      window.xxx=xxx;
    })();
    
    //=>JQ
    $(function(){
       //...这样写在某些角度上也是为了减少全局变量
    });
    
    .....
    
  2. 基于LET/CONST/CLASS等创建变量,会把所在的大括号(除对象的大括号之外)当做一个全新的私有块级作用域

    • 函数执行会产生私有的栈内存(作用域/执行上下文)
    • let等也会产生私有的块作用域(var不会)
    if(1===1){
    	var a=10;
    }
    console.log(a); //=>10  a是全局作用域
    
    if(1===1){
        //=>let会有块作用域(现在大括号就是一个私有作用域)
        //=>a是私有变量
    	let a=10;
    }
    console.log(a);//=>Uncaught ReferenceError: a is not defined