美文网首页
神马叫“闭包”???

神马叫“闭包”???

作者: ea203453e188 | 来源:发表于2017-06-22 16:06 被阅读24次

    本文参考博客:
    1. http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

        2.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures (官方的)
    

    第一步:理解链式作用域

    答:Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 不同于块级作用域哦!

    function f1(){
        var n=999;
        function f2(){
          alert(n); // 999
        }
      }

    如上,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

    第二: 对于阮老师博客的理解补充

    阮老师在闭包博客中说:它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

    第一点是认同的,但第二点有点不敢苟同(初生牛犊,如有错误,还请大神留言指教)。

    阮老师的js代码:

    function f1(){
        var n=999;
        nAdd=function(){n+=1} // 全局变量
        function f2(){ // 局部变量
          alert(n);
        }
        return f2;
      }

    var result=f1(); // 因为这里改变了f2的作用域,所以f2才一直在内存中。 作用域由(f1()内部变量 ——》f1()平级)。

    result(); // 999

    nAdd(); // 由结果看,下面的值为1000,说明nAdd() 执行了, 因为f2作用域被改变后就一直在内存中,所以f1也一直在内存中。

    result(); // 1000

    // 我如果这样写,换一种方式调用,不改变f2的作用域
    
      f1()(); // 999     执行完毕,f2的内存空间被销毁。 f1的内存空间也被销毁,nAdd虽然是全局变量,但其是方法的属性,自然也被销毁。
    
      nAdd();             // undefined     
    
      f1()();              // 还是999
    

    由上面我们可以提出几点疑问:

    1.注意变量的访问范围和生命周期
    2.方法内部的全局变量会随着方法的销毁而销毁。 注意变量的访问范围和生命周期!
    3.第二种调用方式:立即执行函数。

    一句话总结:
    1.闭包就是能够读取其他函数内部变量的函数(是其他函数的内部函数)。
    2.定义在一个函数内部的函数"。

    3.闭包就是将函数内部和函数外部连接起来的一座桥梁。

    4.由于js其特殊的作用域规则,要通过外部来访问函数的内部变量。 ——————闭包就是干这个的!

    补充

    代码理解:

    function f1(){
    var n=999;
    nAdd=function(){n+=1;return n;} // 全局变量:都可以调用,前提是创建了-----销毁之前外部可以访问。
    function f2(){
    alert(n);
    }
    return f2;
    }
    alert(f1()); // 调用f1,返回f2 不调用f1都不会创建nAdd
    alert(nAdd());

    相关文章

      网友评论

          本文标题:神马叫“闭包”???

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