美文网首页
JavaScript闭包(closure)

JavaScript闭包(closure)

作者: pz明 | 来源:发表于2017-08-16 17:20 被阅读31次

    一、概述

     什么是闭包?MDN中第一句话就是

    A closure is the combination of a function and the lexical environment within which that function was declared

     也就是说closure=function+lexical environment,lexical environment即是function声明的地方,然而这并不容易理解,或者说有点概念化,之后又参考了几篇文章,终于初步理解了闭包。

    二、常见闭包

     我们通常见到的闭包往往是这样的,例一:

    function exam(){
      var a=3
      function fn(){  //closure
         alert(a)
      }
     fn()
    }
    

     也就是说闭包常以函数嵌套的方式出现,但是根据闭包的定义,以下例子也是闭包,例二:

    var a=3
    function(){  //closure
      return a
    }
    

     那么为什么我们常见的是第一种嵌套函数样式的闭包呢?原因就在于闭包的用途,我们有时需要隐藏一个变量,但是又不能完全不可引用,这个时候就用到了闭包。
     如同例一中的a,在全局环境中本无法直接访问到,但是我们通过闭包,外界环境就可以访问到a,这里exam()的存在事实上只是使a变成了局部变量而已,也就是说,例三:

    !function(){
      a=3
      function fn(){
        alert(a)
      }
      fn()
    }()
    

     使用一个立即执行的外层函数实际上可以达到同样的效果。

    三、重要特性

     闭包有一个重要特性,即是状态的保持,我们知道,普通函数是不会保存状态的,如,例四:

    function fn(){
      var a=0;
      console.log(++a);    
    }
    fn();  //1
    fn();  //1
    fn();  //1
    

     显然,这里的fn函数无论调用多少次都是输出1,下一个例子,例五:

    function fn(){
      var a=0;
      return function(){  //closure
        console.log(++a);   
      }
    }
    var aFn=fn();
    aFn();  //1
    aFn();  //2
    aFn();  //3
    

     例五中每调用一次,原来的a就加了1,这就说明原来的fn中return的匿名函数的所处环境被保留了(即使此时fn本身已经被清除了),说明aFn自己保持了他所处环境(lexical environment)的引用。

    四、总结

     说了这么多我感觉概念性的东西太容易把人绕晕,可能我们经常在使用它的时候反而没那么在意闭包的概念,值得一提的是个人认为闭包的状态保持是一个很有意思的东西。

    相关文章

      网友评论

          本文标题:JavaScript闭包(closure)

          本文链接:https://www.haomeiwen.com/subject/xngirxtx.html