定义:闭包是由函数以及创建该函数的环境组合而成。这个环境包含了这个闭包创建时所能访问的所有局部变量
理解:能够读取其他函数的内部变量的函数,并开辟新的作用域(环境)

例子1

       function parent() {
              var a = 0;    
        
              function child() {
                console.log(a);
                a++;
              }
              return child;
            }
        
            var p = parent(); 
            p(); 
       p();

 

 

 

 也可以用立即执行函数写

              var parent = function() {
                  var a = 0;
            
                  function child() {
                    console.log(a);
                    a++;
                  }
                  return child;
                }()
            
                parent()
                parent()

两次的结果是为0,1

变量a属于私有变量,保存在同一作用域(环境)的内存中
child函数就相当于闭包函数
再次调用函数p,变量a不会再次声明

例子2

          function parent(a) {
              function child(b) {
                console.log(a + b)
              }
              return child;
            }
        
            var p = parent(1);
            p(3);
        
            var p1 = parent(11);
            p1(3);

         

p和p1共享相同的函数,但是保存在两个不同的作用域,所以不会互相影响

 

闭包用途

  1.针对共享同一个作用域的情况

  2.针对变量只在当前函数的使用,避免污染全局变量

 

例子3

        for (var i = 0; i <= 4; i++) {
              setTimeout(function() {
                console.log(i)
              }, 0)
            }

循环在setTimeout函数开始前就已经执行完毕了,所以得到的i都是最后一项
所以为每一个函数都创建一个作用域,不再共享同一作用域

       for (var i = 0; i <= 4; i++) {
              setTimeout(test(i), 0)
            }
        
            function test(i) {
              return function() {   //闭包
                console.log(i)
              }
            }
        
        或者
  
for (var i = 0; i <= 4; i++) { test(i) } function test(i) { setTimeout(function() { console.log(i) }, 0)      }

还可以用let声明变量,let属于块级作用域

             for (let i = 0; i <= 4; i++) {
                  setTimeout(function() {
                    console.log(i)
                  }, 0)    
                }

 

闭包注意

  由于闭包中的变量保存在内存中,处理速度和内存消耗方面有负面影响,如果不是特殊任务,使用闭包是不需要的