zoukankan      html  css  js  c++  java
  • js中的闭包

    在正文前面普及一下:

      js定义的变量分为全局变量和局部变量

      js可以在函数内部调取全局变量

      js函数外部不能取到函数内部定义的变量

      js平级函数不能相互读取函数内部定义的变量

      js闭包特殊之处就是函数2可以得到函数1的私有变量

    --------------------------------------------------------------------------------------我是分割线------------------------------------------------------------------------------------------------------------------

    什么是闭包?

    百度给出的答案是:指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。

    说实在的这句话反正我是没看懂,查阅书籍,发现闭包是指有权访问另一个函数作用域的变量的函数,常见创建闭包的方式就是在一个函数内部在创建另外的函数,

    例如:

    function funct1(){
        var num1="10";
        function  funct2(){
              alert(num1);   
        }
         return funct2;      
    }    
    var obj = funct1();
    obj();

    当然上面的例子funct1也可以直接返回一个匿名函数,

    通过概念和案例,我对闭包的理解就是:能够获取函数内部私有变量的函数,

    而在js的语法中,只有函数内部的子函数才能获取私有变量,所以闭包要写在函数内部,

    闭包有两大作用:

      1、访问函数内部的私有变量,

      2、函数内部的私有变量不会被回收

    1不用解释,2原因是将函数funct1返回的funct2函数赋给全局变量obj,此时funct2也是全局函数,而funct2函数有调用函数funct1的私有变量,级funct2函数依赖于funct1函数,因此funct1函数也会保留在内存里,不会被回收。

    注意因为闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,过度使用闭包会导致内存占用过多;闭包会在父函数外部改变父函数的私有变量,所以若将父函数当对象使用,把闭包当共有方法,把内部变量当成私有属性,这时切记请勿轻易改变父函数内部变量的值

    说起闭包就需要引入作用域链,作用域链这种机制引入一个很大的副作用,即闭包只能获取包含函数中任何变量的最后一个值,如下面闭包:

    function funct1(){
          var result = new Array();
          
         for(var i=0;i<10;i++){
            result[i]= function (){
                    return i;
            }
        }
         return result;             
    }  
    var functs=funct1();
    for(var i=0;i<functs.length;i++){
      console.log(functs[i]())
    }

    这个函数我们期望的是输出从0到9的数,可是事实并不是这样,它输出了10个10,也就是闭包输出的每次都是funct1函数变量i的最后一个值(10),这当然不是我们所期望的,这时需要引入一个匿名函数强制让闭包的行为符合预期:

    function funct1(){
         var result = new Array();
           
        for(var i=0;i<10;i++){
            result [i] = function (num){
                return function(){
                      return num;    
                }        
            }(i);
        }
    }
    var functs=funct1();
    for(var i=0;i<functs.length;i++){
      console.log(functs[i]())
    }
    
    

    此时运行此闭包就能完美输出从0到9的数,现在我们分析一下,这测版本中我们并没有直接把闭包赋值给数组,而是定义了一个匿名函数,并将立即执行匿名函数所得的结果赋给数组,这里的匿名函数有一个参数num,也就是最重要返回的值,在调用每个匿名函数时我们传入了变量i,由于函数参数是按值传递的,所以就会将变量i的当前值赋给num,而这个匿名函数内部有创建并返回了了一个访问num的闭包,这样result数组中的每个函数都有自己num变量的一个副本,因此就可以返回各自不同的数值了

    当然this在闭包中也是比较好玩的,

    var  num=10;
    
    var obj= {
         num=20;
         alertNum;function(){
             return function(){
                 return this.num;
            }
        }      
    }
    
    alert(obj.alertNum()());    //输出10

    内部函数在搜索this和arguments两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量,不过把外部作用域中的this对象保存在一个闭包能够访问的变量里,就可以让闭包访问该对象了,如下面代码

    var  num=10;
    
    var obj= {
         num=20;
         alertNum;function(){
             var that = this;
             return function(){
                 return that.num;
            }
        }      
    }
    
    alert(obj.alertNum()());    //输出20
  • 相关阅读:
    JAVA HDFS API Client 连接HA
    jdo pom
    iOS/OC 笛卡尔积算法 递归求笛卡尔积 求N个数组中元素任意组合
    Tableview如何实现流畅的展开折叠?
    iOS证书那些事儿
    iOS 状态栏颜色设置
    iOS 可以正常跳转WEB支付宝 无法跳转支付宝APP
    iOS代码管理工具的使用
    *** Assertion failure in -[UICollectionView _createPreparedSupplementaryViewForElementOfKind:atIndexPath:withLayoutAttributes:applyAttributes:]1555错误
    iOS UISearchBar 设置光标颜色和取消按钮颜色
  • 原文地址:https://www.cnblogs.com/teersky/p/7279841.html
Copyright © 2011-2022 走看看