zoukankan      html  css  js  c++  java
  • 闭包认知的总结————终极版啦!

                                 闭 包 翻 篇

    前言:看了好多博客,每次都是当时看,过后就忘,理解的一点都不深刻,所以打算自己认真写一篇,先向参考的博客作者致敬。

             本文参考博客:
            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());
  • 相关阅读:
    安卓学习第一课——电话拨号器
    CodeForces 644B【模拟】
    hdu5861【线段树】
    CodeForces 41A+43A【课上无聊刷水题系列】
    hdoj5493【树状数组+二分】
    HDU5894【组合数学】
    Codeforces643A【一种暴力】
    CodeForces 689C【二分】
    CodeForces 665B 【水-暴力】
    CodeForces 653A【水】
  • 原文地址:https://www.cnblogs.com/njqa/p/6419854.html
Copyright © 2011-2022 走看看