闭包

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;  
}  

 
 
原文地址:https://www.cnblogs.com/laiso/p/7884435.html