美文网首页
简明闭包

简明闭包

作者: oopsist | 来源:发表于2017-09-26 21:09 被阅读2次

    闭包向来是javascript的难点之一。

    1.定义
    2.闭包是如何产生的
    3.不仅仅是词法作用域

    一 定义

    闭包可以看作是javascript函数的一种特性。

    二 闭包是如何产生的

    从程序语言的角度来看,闭包产生的原因,就是基于词法作用域的作用域链的访问规则。

    javascript中作用域只有两种类型,天生的全局环境和函数调用生成的局部环境。

    嵌套的调用会产生多个嵌套的环境,就像栈那样。

    1.png

    对于语言的设计者来讲,就有了一个必须解决的问题,那就是:当你在局部作用域里找不到某一个标识符的时候,是否跨作用域寻找。
    最简单粗暴的策略是,找不到就报错,不容许跨作用域找查。

    /* 1.0 */
    var a=10;
    function fun_1(){
            console.log(a);
    }
    fun_1();            //如果语言被设计为不容许跨越作用域 那么这段代码报错
    

    这种设计比较简(愚)单(蠢),函数无法获得外部的任何信息,如果必要,信息要以参数的形式传入。

    第二种策略,容许标识符的解析跨越作用域,也就是说,这个作用域里找不到这个标识符,那么就到上一个作用域中去找(当然不能去下一个,因为下一个作用域还没有生成呢)。
    几乎所有的编程语言都支持这种策略,但是在这种策略的具体实现上,设计者们产生了分歧,一个新的问题是: 到底谁才是上一个作用域?。
    由于函数调用就像栈的压,出,理所当然的一种策略就是,按调用的顺序来,每一个调用者的作用域都是被
    调用者的上一个作用域,就也就是动态作用域。

    /* 1.1 */
    var a=10;
    function fun_1(){
            console.log(a);
    }
    fun_1(); // 输出10
    (function(){
    var a='xxx';
    fun_1();//输出 ‘xxx’
    })();
    

    这种动态作用域,很依赖于函数调用的位置,不同的位置,函数访问的上一个作用域也不相同。
    javascript的设计者明显不喜欢这样的设计,语言的设计者,希望函数的上一个作用域,在声明或者是定义的那个地方就确定了,就像一个隐藏的bind。
    正所谓,javascript函数运行在它们被定义的作用域内,而不是它们被执行的作用域内,这就是所谓的词法作用域,与函数在那里调用无关。

    /* 1.2 */
    var a='galbol';
    function fun_1(){
              console.log(a);
    } //全局环境下定义
    fun_1(); // 输出'global'    //全局环境下调用
    (function(){
    var a='xxx';
    fun_1();//输出 ‘global’  //嵌套在函数中调用
    })();
    

    这个例子可以看到,我们在全局作用域中定义了函数fun_1,所以,fun_1的上一个作用域即全局作用域,不管在那里被调用,都不会被影响。
    这样就产生了闭包,当然上述的例子很单调,无法展现闭包的强大之处,看一下这个例子。

    /* 1.3 */
    function fun_1(){
      var x=100;
    return function(){
      console.log(x);
      }
    }
    fun_2=fun_1();
    fun_2() //输出100
    

    fun_1中定义了一个匿名函数,根据词法作用域,匿名函数的上一个作用域,也就是fun_1调用时生成的局部作用域,即时fun_1调用完毕,这个作用域也不能被垃圾回收处理,因为返回的这个匿名函数,可能使用了fun_1局部作用域中的数据,也只有这个匿名函数能够访问到这个局部作用域中的数据,这就是闭包的强大之处。
    <h3>3.不仅仅是词法作用域</h3>
    在javascript中,有两个特殊的例子
    this this在javascript是个关键字,它的值取决于调用位置,即动态的。
    Function构造函数生成的函数,也是闭包,不过函数的上一个作用域永远是全局作用域,而不是声明和定义它们的地方。

    相关文章

      网友评论

          本文标题:简明闭包

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