谈谈我对闭包的理解

闭包

定义

在MDN上的定义为:函数和对其周围环境的引用捆绑在一块儿构成闭包,可让使用者从函数内部访问外部函数的做用域。闭包

  • 定义中的周围环境指的是词法环境或者叫词法做用域。做用为根据源代码中声明变量的位置来肯定该变量在何处可用。

所以,闭包能够通俗的理解为:函数与函数内部能访问到的变量的总和。函数

形如code

function funA(){  
 var a = 10;  
 return function(){  
 console.log(a)  
 }  
}  
​  
var b = funA();  
b();

做用

  1. 能够在函数的外部访问到函数内部的局部变量
  2. 可让这些变量始终保存在内存中,不会随着函数的结束而自动销毁

闭包为何存在

其做用就是闭包存在的意义。内存

首先,JS和其余语言同样,拥有做用域,其最大的做用就是隔离变量。而且做用域存在上下级关系,由函数是在哪一个做用域下建立所肯定。作用域

变量取值的过程是先在当前做用域查找值,若是没有则会跳转到上级做用域查找,若是找到就中止,未查找到这继续查找上级做用域直到全局做用域中。io

var a = 10;
function fn(){
    var b = 20;
    function bar(){
        console.log(a + b)
    }
    return bar
}

var x = fn(),
    b = 200;
x() //值为10+20=30

变量取值的过程就像一个单向链表,只能从当前做用域开始向上级做用域查找,所以咱们也将这个查找过程称为做用域链。console

从上面能够看到,函数内部能够访问到外部的变量,而外部没法访问到内部做用域的变量。因此在某些状况下,咱们不想某个变量直接暴露,就将这个变量保存在函数中,使其变为局部变量,再使用闭包将其“间接暴露”。function

(function countNum(){
    var num = 0;
    window.addNUm = function (){
        num++;
        console.log(num)
    }
    window.reduceNum = function (){
        num--;
        console.log(num)
    }
}())

在这个例子中,要想改变num的值,只能经过addNumreduceNum两个函数。变量