zoukankan      html  css  js  c++  java
  • 闭包

    1,闭包的定义:
    In computer science, a closure is a function together with a referencing environment for the nonlocal names (free variables) of that function.
    根据字面意思:一个拥有作用域的函数对”非本地“声明的变量的引用。
    2,词法作用域:函数的执行依赖于变量作用域,这个变量作用域是在本函数定义的时候定义的,而不是根据函数调用时所在的作用域决定的。
    3,作用域链:
     1>.域(如果学过c++的话,和命名空间很相似):JavaScript中的上下文是一个 全局作用域,每一个函数都是一个域,这个域中有域本身的变量与行为。
       域分为父域与子域。例如:
    function f1() {
       
        var = 0;
       
        function f2() {      
            alert(n);    
        }
        
        return f2;
      
    }
    此时f2作为f1的子域,而f1作为f2的父域。而f1和f2都作为全局作用域的子域,所一f2中可以访问f1中的n;
    需要注意的是:在子域中可以对父域中的变量进行访问,但是父域在没有闭包的情况下是不能对子域的变量进行访问.这个就是作用域链:
    就是在子域中的找不到的元素自动返回父域中找,一次次循环,类似于递归算法。如果没找到就返回一个undifned。
    4,一个简单的例子:
    var scope1='global scope';  
    function checkscope1(){  
          var scope1="local scope";  
          function f1(){return scope;}  
          return f1;  
    console.log(checkscope1()()); //
    local scope

    把在全局声明的
    checkscope1()看作一个全局变量,当然也是一个域,
    f1是定义在
    checkscope1()函数中的“子”函数,可以对父级函数的变量进行引用,由于f1是作为
    checkscope1()的返回值(也就是作为一个结果),所以当调用
    checkscope1()的时候,f1被作为返回值出现在了全局作用域中,由于词法作用域,f1的执行依赖于变量所在的作用域,所以
    f1可以引用父函数的变量,所以结果是
    local scope;
    再看一遍定义:在全局作用域中对并不是在全局作用域定义的变量(
    scope1="local scope"
    )进行引用,这就是一个闭包,而从技术上讲,每一function都是一个闭包。
    5,闭包的作用:
     1>读取函数内部的变量
     2>是函数内部的值始终存在于内存中。
    6,闭包与for的混用:
     function constfuncs(){  
          var funcs=[];  
          for(var i=0;i<10;i++){  
            funcs[i]=function(){ return i ;}  
          }  
            return funcs;  
    }  
        var funcs=constfuncs();  //此时的i已经递增到了10;
        console.log(funcs[5]()); //10
    funcs是一个函数数组,而不管funcs的index是什么结果都是返回10。
    原因:
    首先此时要理解函数数组元素中的i是值传递而不是引用传递。也就是说i的取值是决定于i的最终值。
    funcs是一个函数数组,这个数组里边的元素都是未执行的函数。当执行的时候,由于词法作用域,就返回到父域中去找i,此时i的最终值为10,所以函数数组的每一个i都是10.
    解决方案:
    匿名函数的自我执行:
     1> function constfuncs(){  
          var funcs=[];  
    for(var i=0;i<10;i++){  
    (function(i){
          
     funcs[i]=function(){ return i ;}
     
    })()
       
     
    }  
         return funcs;  
    }  
    2,
     function constfuncs(){  
          var funcs=[];  
          for(var i=0;i<10;i++){  
            funcs[i]=(function(){ return i ;}).(i);  
          }  
            return funcs;  
    3.匿名函数自我执行的时候赋值给一个变量,那么自执行函数的括号是可以去掉的。
     function constfuncs(){  
          var funcs=[];  
          for(var i=0;i<10;i++){  
            funcs[i]=function(){ return i ;}(i);  
          }  
            return funcs;  
    }  

     
     
  • 相关阅读:
    怎么强制限制div宽度
    KeyWordHelper关键字提取类(注:使用第三方组件DictSeg.dll)
    XmlToJsonxml对象转换为Json对象类
    Excel模板导出(针对复杂报表的一种解决方式)
    SQL查询xml内容
    ASP.NET中使用jQGrid
    RandomHelper随机数辅助类
    Translater语言翻译类
    Int32.Parse, Convert.ToInt32,Int32.TryParse三者的区别
    CollectionHelper网页采集辅助类
  • 原文地址:https://www.cnblogs.com/laiso/p/7884435.html
Copyright © 2011-2022 走看看