您的位置:首页 > Web前端 > JavaScript

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

2014-05-29 22:33 585 查看
  闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式为:在一个函数内部创建另一个函数。

  “当某个函数被调用时,会创建一个执行环境(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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: