zoukankan      html  css  js  c++  java
  • js闭包实例汇总

    Js闭包
    闭包前要了解的知识

    1. 函数作用域
    (1).Js语言特殊之处在于函数内部可以直接读取全局变量

    代码如下:

    <script type="text/javascript">
    var n=100;
    function parent(){
      alert(n);
    }
    parent();//100
    </script>
    

    如果在php里  代码如下:

    <?php
    $n=100;
    function parent(){
      echo $n;
    }
    parent();//会报错 n未定义
    ?>
    

    (2).在函数外部无法读取函数内的局部变量

    代码如下: 

    <script type="text/javascript">
    function parent(){
      var m=50;
    }
    parent();
    alert(m);//报错 m未定义
    </script>
    

    注意函数内部声明变量时一定要加var,否则就声明了一个全局变量

    代码如下:

    function parent(){
    m=50;
    }
    parent();
    alert(m);//50
    

    //当然在php里更是如此了,  

    代码如下:

    <?php
    function parent(){
      global $m;//全局 ,定义与赋值要分开
      $m=50;
    }
    parent();
    echo $m;//50
    ?>
    //没global的话,一样会报没定义的错误
    

    有时,需要得到函数内部的的局部变量,就需要变通的方法实现利用js变量作用域的特点,如在函数内部定义子函数,对于子函数来说,父函数就是它的全局,子函数可以访问父函数里的变量(对于整个js代码来说又是局部变量)

    代码如下:

    <script type="text/javascript">
    function parent(){
       var m=50;
       function son(){
            alert(m);
       }
       return son;
    }
    var s=parent();//将结果保存在全局里
    s();//50
    </script>

    Parent内部所有局部变量对其子函数来说都是可见的,但其子函数内的局部变量对其父函数是不可见的,这就是js特有的链式作用域结构,子对象会一级一级地向上查找所有父对象的变量,父对象的所有变量对子对象都是可见的,反之不成立!上面的son函数就是闭包

    有些同学可能这样

    代码如下:


    function parent(){
       var m=50;
       function son(){
            alert(m);
       }
    }
    parent();
    son()//会报 函数son未定义
    

    注意 在javascript里,在函数里声明的函数都是局部的,函数运行完后就释放了

    注意这点与php的区别

     代码如下:

    <?php
    function parent(){
      function son(){
          $m=50;
          echo $m;
      }
    }
    parent();
    son();//输出50 不会报错
    ?>
    

      

    闭包

    函数内部定义函数,连接函数内部和外部的桥梁
    闭包的作用有2个:
    一是前面提到的读取函数内部的变量,
    二是让这些变量的值保存在内存中,实现数据共享
    下面是几个闭包的例子

    代码如下:

    <script type="text/javascript">
    var cnt=(function(){
        var i=0;
        return function(){
            alert(i);
            i++;
        }
    })();
    cnt();//0
    cnt();//1
    cnt();//2
    cnt();//3
     
    
    </script> 

    把匿名函数的执行结果(即对里面子函数的声明赋给全局变量cut),i就保存在内存里了
    执行cut()时就直接从内存取值了,i只有cnt()函数才能调用,直接alert(i)是不行的
    还可以向闭包内传参

    代码如下:

    var cnt=(function(num){
    return function(){
        alert(num);
        num++;
      }
    })(5);
    cnt();//5
    cnt();//6
    cnt();//7
    //当然还可以调用时传参
    var cnt=(function(){
        var i=0;
    return function(num){
        num+=i;
        alert(num);
        i++;
      }
    })();
    cnt(1);//1
    cnt(2);//3
    cnt(3);//5

    为了对闭包有更好的理解,我们看以下代码
    比如我想返回一个数组,数组里面有5个函数,第一个函数弹出0,第二个弹出1...  
    代码如果这样写

    代码如下:

    function box(){
      var arr=[];
      for(i=0;i<5;i++){
          arr=function(){return i;}
        }
    return arr;   
    }
    var a=box();
    alert(a);//包含五个函数体的数组
    alert(a[0]());
    alert(a[1]());

    弹出的函数体
    function(){return i;}    }
    最后这个i是4,之后++成为5
    For循环停止
    发现均弹出5,明显不符合我们的要求

    解决方案1
    自我即时执行里面的函数

    代码如下:
    function box(){
      var arr=[];
      for(i=0;i<5;i++){
          arr=(function(num){return i;})(i);
        }
    return arr;   
    }
    var a=box();
    for(var i=0;i<a.length;i++){
      alert(a);
    }

    但是我们发现 返回的数组里的元素是函数执行的结果,但我们想要的是函数有得升级我们的代码

    解决方案2
    闭包实现

    代码如下:
    function box(){
    var arr=[];
            for(var i=0;i<5;i++){
     
    
                     arr=(function(num){
                         return function(){return num;}
                     })(i);
    
             }
    return arr;         
    }
    
    var arr=box();
    
    for(var i=0;i<5;i++){
    
        alert(arr());//0,1,2,3,4
    }

    关键代码

    代码如下:
    arr=(function(num){ 
             return function(){return num;}
    })(i);
     
    
    
    i=0 时 
    arr[0]=(function(num){return function(){return num;}})(0);
    
    1时
    
    
    arr[1]=(function(num){return function(){return num;}})(1);  

     以上就是闭包的好处!非常简单实用吧。

      

      

     

  • 相关阅读:
    Python常用代码: 获取本机ip;统一十进制和日期;日期计算
    gogs安装(docker)
    【转载】os.environ模块环境变量详解
    。。
    IDEA配置Scala
    jupyter 安装
    docker基本操作
    2021秋季加分项
    docker安装
    spark Windows环境的部署
  • 原文地址:https://www.cnblogs.com/mmzuo-798/p/7402920.html
Copyright © 2011-2022 走看看