闭包及闭包优缺点

1. 闭包的概念

通俗理解:闭包是能够读取其他函数内部变量的函数;
闭包 = 内层函数 + 引用的外层的函数变量 ; 即内层函数引用外层函数的变量就构成了闭包。
闭包作用:闭包可以保护函数的私有变量不受外部的干扰,将上级作用域的引用保存下来,实现方法和属性的私有化
常见的创建闭包的方式:在一个函数内部嵌套函数,内部函数引用外层函数中定义的变量;如下图所示:

//闭包 1: 2-5 行构成一个闭包
1  function outer() {
    
    
2              let name = 'andy';
3              return function() {
    
    
4                 console.log(name);
5              }
6          } outer()();

//闭包 2: 2-6 行构成一个闭包 
1  function outer() {
    
    
2              let name = 'andy';
3              function inner() {
    
    
4                  console.log(name);
5             }
6              inner();
7          }
8          outer();

2. 闭包的优缺点

优点:

  1. 避免全局污染;
  2. 变量长期存储在内存中; 在函数体内,随着函数每一次执行完毕,函数内部定义的对象(如果没有被闭包函数引用),会被销毁;如果被闭包引用,则被保留下来。所以闭包的存在,导致变量不会被销毁,保留了下来,从而长期存储在内存当中;

缺点:

  1. 内存泄漏(消耗):应用程序中不再用到的内存,由于某些原因,无法及时释放,导致了内存的泄漏。
    闭包的存在,使得某些变量不能被及时销毁,内存也无法及时释放,也就导致了内存的泄漏。但是闭包存在,不一定就会导致内存泄漏。 闭包导致内存的泄漏只存在 IE 浏览器中,其他浏览器中不会导致内存的泄漏。
  2. 常驻内存,增加内存使用量:这个内存浪费不仅因为它常驻内存,更重要的是,对闭包的使用不当,会造成无效内存的产生;
  3. 性能问题:使用闭包时,会涉及跨作用域的访问,每次访问都会导致性能损失;

3. 闭包应用场景

  1. 实现模块化;
  2. 实现变量的私有封装;
  3. 实现迭代器;

4. 当 this 碰上闭包

在非严格模式下,一般来说,闭包中的 this 指向 window,严格模式,闭包中的 this 为 undefined;

var  uname  =  "window"; 
var  object = {
    
                 
    		uname : "object",
    		fun: function() {
    
                     
        			console.log(this.uname);  // object  由 Object对象调用,this 指向 Object          
        			return  function() {
    
                        
           				console.log(this.uname);  //window   闭包 普通函数调用,指向 window      
        			}             
    			} 
} 
object.fun()();

5. 闭包的销毁

在模块或应用执行完成后,将内层函数赋值为 null 即可,如 inner( ) = null;

6. 闭包的常见理解误区

  1. 闭包一定要有 return 将函数返回 (错)
    下图的闭包不包含 return,可见 return 不是构成闭包的必要条件。
//闭包 2: 2-6 行构成一个闭包 
1  function outer() {
    
    
2              let name = 'andy';
3              function inner() {
    
    
4                  console.log(name);
5             }
6              inner();
7          }
8          outer();
  1. 闭包一定导致内存泄漏 (错)
    只有 IE 浏览器中的闭包才有可能导致内存的泄漏,其他浏览器不会。闭包可能导致内存的泄漏,不是一定会导致内存泄漏。

7. 调试器查看闭包

谷歌浏览器为例:

  1. 打断点,页面刷新
    请添加图片描述
  2. 点击单步按钮,查看代码执行顺序。当代码运行到第 14 行时,显示 Closure(outer)即闭包。
    在这里插入图片描述

参考文章推荐:

  1. 正确理解闭包
  2. 作用域对性能的影响;

猜你喜欢

转载自blog.csdn.net/qq_45050686/article/details/126925356