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

    本文是通过实例来帮助大家深刻理解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);  
      以上就是闭包的好处!非常简单实用吧。
  • 相关阅读:
    Notice: Only variable references should be returned by reference(PHP版本兼容性问题)
    App 开发:Hybrid 架构下的 HTML5 应用加速方案
    Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?
    前端切图+网页排版的注意事项和经验分享
    php提示 Notice: Use of undefined constant name
    如何预测一个互联网产品的未来—一套关于产品的数学模型
    以 MAMP 为 Mac OS X 安装并设置 PHP开发环境
    关于EINTR错误的理解【转】
    socket中的函数遇见EINTR的处理【转】
    Ubuntu10.04中利用V4L2读取摄像头数据并保存成文件【转】
  • 原文地址:https://www.cnblogs.com/hellman/p/4353300.html
Copyright © 2011-2022 走看看