• JS闭包


     1 <!DOCTYPE html>
     2 <html>
     3     <head>
     4         <meta charset="UTF-8">
     5         <title></title>
     6     </head>
     7     <body>
     8         <script type="text/javascript">
     9 //            第一,函数作为返回值
    10             function fn(){
    11                 var max = 10;
    12                 
    13                 return function bar(x){
    14                     if(x > max) {
    15                         console.log(x);
    16                     }
    17                 };
    18             }
    19             var f1 = fn();
    20             f1(15);
    21 
    22         </script>
    23         <script type="text/javascript">
    24                         
    25 //            第二,函数作为参数被传递
    26 
    27             var max = 10;
    28             fn = function(x){
    29                 if(x > max){
    30                     console.log(x);//15
    31                 }
    32             };
    33             (function(f){
    34                 var max = 100;
    35                 f(15);
    36             })(fn);
    37         </script>
    38         <script>
    39             function fn(){
    40                 var max = 10;
    41                 
    42                 return function bar(x){
    43                     if(if > max){
    44                         console.log(x);
    45                     }
    46                 };
    47             }
    48             var f1 = fn();
    49                 max = 100;
    50             f1(15);
    51 
    52         </script>
    53     </body>
    54 </html>

    第一步,代码执行前生成全局上下文环境,并在执行时对其中的变量进行赋值。此时全局上下文环境是活动状态。
    全局上下文环境:max是undefined


    第二步,执行var f1 = fn();代码时,调用fn(),产生fn()执行上下文环境,压栈,并设置为活动状态。
    fn()上下文环境:max是10


    第三步,执行完var f1 = fn();,fn()调用完成。按理说应该销毁掉fn()的执行上下文环境,但是这里不能这么做。
    注意,重点来了:因为执行fn()时,返回的是一个函数。函数的特别之处在于可以创建一个独立的作用域。
    而正巧合的是,返回的这个函数体中,还有一个自由变量max要引用fn作用域下的fn()上下文环境中的max。
    因此,这个max不能被销毁,销毁了之后bar函数中的max就找不到值了。因此,这里的fn()上下文环境不能被销毁,还依然存在与执行上下文栈中。
    执行到max = 100;时,全局上下文环境将变为活动状态,但是fn()上下文环境依然会在执行上下文栈中。
    另外,执行完max = 100;,全局上下文环境中的max被赋值为100。
    全局上下文环境:max是100 fn()上下文环境:max是10


    第四步,执行到f1(15);,执行f1(15),即执行bar(15),创建bar(15)上下文环境,并将其设置为活动状态。
    执行bar(15)时,max是自由变量,需要向创建bar函数的作用域中查找,找到了max的值为10。
    这里的重点就在于,创建bar函数是在执行fn()时创建的。fn()早就执行结束了,但是fn()执行上下文环境还存在与栈中,因此bar(15)时,max可以查找到。如果fn()上下文环境销毁了,那么max就找不到了。
    使用闭包会增加内容开销,现在很明显了吧!


    第五步,执行完f1(15);就是上下文环境的销毁过程,这里就不再赘述了。
    闭包和作用域、上下文环境有着密不可分的关系,真的是“想说爱你不容易”!
    另外,闭包在jQuery中的应用非常多,无论你是想了解一个经典的框架/类库,还是想自己开发一个插件或者类库,像闭包、原型这些基本的理论,是一定要知道的。否则,到时候出了BUG你都不知道为什么,因为这些BUG可能完全在你的知识范围之外。

    转发请备注出处
    【公众号:缃言的调调】
  • 相关阅读:
    使用Xcode 制作自定义storyboard启动界面,供uniAPP使用。
    由于ios由UIWebView换成了WKWebview内核后导致webview请求接口文件上传,后台接收不到文件
    标准基座获取定位可以获取address城市,自定义基座获取不到address
    WeeklyEnglish 2020
    Maven编译打包时报“PKIX path building failed”异常解决方法
    Spring Security
    在IDEA中导入GIT项目
    利用git上传本地文件、文件夹到Github
    OpenAM
    CentOS 安装 OpenAM
  • 原文地址:https://www.cnblogs.com/zuojiayi/p/6364600.html
Copyright © 2020-2023  润新知