从编译原理浅谈闭包

       刚学完编译原理,再来看闭包这个东西,感觉理解真的深入不少。下面讲一下闭包的一种实现方式,从三个部分解释。

      第一部分:

           当新增一个变量时,计算机会在一块内存空间内分配一个位置,并且记录下这个变量的名称与位置的对应关系。

           而这块内存空间,我们暂且称之为环境。

从编译原理浅谈闭包_第1张图片

   第二部分:

      在执行方法时,计算机会新开辟一块内存空间,用来存放方法中的局部变量。

      下面我们来看一个javascript的例子

var money=100;
   function Add(x){
      return x+money;
   }

     现在我们来看看计算机会干些啥

     第一步:var money=100; 这条程序会让计算机在当前环境中找个位置给money变量,这个环境我们就叫做环境1吧。

                接着是定义方法,同样在环境1中找个位置给Add方法,这个位置存储了方法的执行内容,还有定义时所在的环境,即环境1。

    从编译原理浅谈闭包_第2张图片

   

       第二步: 执行Add方法之前,先开辟一块内存空间(叫做环境2)。

            因为有参数x,所以在环境2中为x找个位置。

            执行内容时,需要查找变量时会先在当前环境(环境2)中找,若找不到就到外面一层环境(环境1)中找。

            因此,x在环境2中,而money在环境1中。

            最后执行结束,我们要考虑环境2会不会被销毁,这个问题下面会继续探讨,当然在这个程序中,环境2会被销毁。

      从编译原理浅谈闭包_第3张图片从编译原理浅谈闭包_第4张图片


     第三部分:

      热身完了,我们来看闭包的实现

     

function A(){
      var count=0;
      
      function B(){
         count++;
         console.log(count);  //显示count的值
      }
    }
   var c=A();
   c();
   c();

       

       首先,定义方法A,当前环境依然假设为环境1。      

       然后就要执行方法A。       

     

     

       执行方法时要开辟一块内存空间,就叫做环境2吧。

      在环境2中定义了count变量,还有方法B。后将方法B返回,由环境1中的c接收。

      现在我们可以看到,c引用方法B,而方法B引用环境2,也就是说环境2依然被外界引用,所以即使方法A执行完了,环境2依然会被保留,count变量依然保留。

    

        

       之后调用方法B时,也就可以在环境2中访问到count变量。

      现在可以猜测第一个c() 显示1,第二个c() 显示2

       确实也是这样。

      

        简单来说,闭包就是保留了一块环境,并且可以通过方法访问到这个环境。

  

      

                                                              


你可能感兴趣的:(其他)