首页 > 代码库 > javascript中的闭包、模仿块级作用域和私有变量

javascript中的闭包、模仿块级作用域和私有变量

  闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式为:在一个函数内部创建另一个函数。

  “当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。然后,使用arguments和其他命名参数的值来初始化函数的活动对象(activation object).但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象出于第三位。。。。。直至作用域链终点的全局执行环境。”

function creawteComparisonFunction(propertyName){
       return function(object1,object2){
             var value1=object1[propertyName];
             var value2=object1[propertyName];
             if(value1<value2){
                   return -1;
             }else if(value1>value2){
                   return 1;   
             }else{
                   return 0;
             }
      };  
}

  在匿名函数从createComparisonFunction()中被返回后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象。更重要的是,createComparisonFunction()函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。或者说,当createComparisonFunction()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然留在内存在,直到匿名函数被销毁后:

//创建函数
var compareNames=creawteComparisonFunction("name");
//调用函数
var result=compareName({name:"gay1"},{name:"gay2"});
//解除对匿名函数的引用(以便释放内存)
compareNames=null;

请看如下代码:

function createFunctions(){
      var result=new Array();
      for(var i=0;i<10;i++){
            result[i]=function(){
                  return i;    
            };   
      }
      return result;
}

首先得确定:这段代码创建了10个闭包,但结果却不是我们想要的,要达到目的,可以这样:

function createFunctions(){
      var result=new Array();
      for(var i=0;i<10;i++){
            result[i]=function(num){
                  return function(){
                        return num;
                  };
            }(i);   
      }
      return result;
}

在这个版本中,没有直接把闭包复制给数组,而是定义了一个匿名函数,并将立即执行改匿名函数的结果赋值给数组。这里的匿名函数有一个参数num,也就是最终的函数要返回的值。在调用每个匿名函数时,我们传入了变量i。由于函数参数是按值传递的,所以就会将变量i的当前值复制给参数num。而在这个匿名函数内部,又创建并返回。了一个反问num的闭包。这样一来,result数组中的每个函数都有自己num变量的一个副本,因此就可以返回各自不同的数值了。

  “javascript没有块级作用域的概念。” 但是可以使用“私有作用域”的匿名函数语法来打到目的:

function outputNumber(count){
     (function(){
           for(var i=0;i<count;i++){
                 alert(i);
           }
     })();
     alert(i);  //报错, 但是如果不实用私有作用域,则正常
}

 

“私有变量”大家一定比我更了解这个,这里就不谈了。注意一个坑就好:

function Person(name){
    this.getName=function(){
        return name;
    };
    this.setName=function(value){
        name=value;
    };
}
var person1=new Person("gay1");
alert(person1.getName());
var person2=new Person("gay2");
alert(person2.getName());
person1.setName("gay3");
alert(person1.getName());    //gay3
alert(person2.getName());    //gay2

/**************邪恶的分割线***********************/

(function(){
    var name="";
    Person=function(value){
        name=value;
    };
    Person.prototype.getName=function(){
        return name;
    };
    Person.prototype.setName=function(value){
        name=value;
    };
})();
var person1=new Person("gay1");
alert(person1.getName());
person1.setName("gay2");
alert(person1.getName());

var person2=new Person("gay3");
alert(person1.getName());    //gay3
alert(person2.getName());    //请注意这里是gay3