闭包的两个作用
从性能角度讲,我们真实项目中应该减少对闭包的使用(因为闭包会产生不释放的栈内存,过多使用容易导致内存溢出或者降低性能)
- 保护
- 保存
-
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(){ //...这样写在某些角度上也是为了减少全局变量 }); ..... -
基于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