您的位置:首页 > 其它

闭包、执行环境、作用域链

2017-01-11 16:11 204 查看
闭包是指有权访问另一个函数作用域中的变量的函数,创建的常见方式就是在一个函数内部创建另一个函数。

我们来理解下执行环境和作用域链:
     1.执行环境有全局执行环境和函数执行环境之分。
     2.每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链。
     3.函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,由底向上乃至全局环境。
     4.变量的执行环境有助于确定应该何时释放内存。

执行环境和作用域链

function createComparisonFunction(propertyName){
     return function(object1,object2){
     var value1=object1[propertyName];
     var value2=object2[propertyName];
     
     if(value<value2){
          return -1;
     }else if(value1>value2){
          retutn 1; 
     }else{
         return 0; 
     }
     };
}
//创建函数
var compareNames=createComparisonFunction("name");
//调用函数
var result=compareNames({name:"joey"},{name:"ross"});
//接触对匿名函数的引用,用于释放内存
compareNames=null;

因为只是用于自己加强理解,就直接把图片放在这里了,因为用于文字实在很难描述出来作用域链的关系。
值得一提的是,每个执行环境都有表示变量的对象--变量对象,全局环境中的变量对象始终存在,而内部函数的局部环境变量则只在函数执行过程中存在。
而在这个例子中,createComparisonFunction()的作用域链包含两个变量对象,一个本身的活动对象,一个全局变量对象,而匿名函数的作用域链包含着三个对象变量,多了一个自身的闭包活动对象,外面访问不进来,里面却可以访问外面,所以也包含外部函数的活动对象和全局变量对象,重要的是,当外部函数执行完毕之后,它的活动对象也不会被销毁,因为匿名函数的作用域链接仍然在引用这个活动对象,换句话说,外部函数返回后,其执行环境会销毁,但是它的活动对象依然留在内存中,知道匿名函数被销毁,外部函数的活动对象才会被销毁。



闭包与变量

function create(){
     var result=new Array();
     for(var i=0;
i<10, i++){
          result[i]=function(){
              return i
          }
     }
}
//蓝色的全局变量对象,红色的是create()函数活动对象,绿色的闭包的活动对象。

作用域链的这种配置机制引出一个值得注意的副作用,闭包只能取得包含函数中任何变量的最后一个值。
上面这句话是重点,这个代码我起初没看懂的,反复理解了之后才懂,这个函数会返回一个函数数组,[0(),1().....9()],从0到9,而函数返回的 i  值应该对应函数名称,即是0()里面返回0,1()里面返回1,以此类推,实际上每个函数返回的都是10,因为 create()这个函数的作用域链保存这这个函数的活动对象,活动对象有result,还有i,函数调用后,变量 i 的值已经是10,并且保存在活动对象里,此时闭包去引用的都是同一个
i 。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息