闭包

闭包是指有权访问另一个函数作用域中的变量的函数。

闭包示例

  • 在匿名函数从createComparisonFunction()中被返回后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象,匿名函数就可以访问其中定义的所有变量。
  • createComparisonFunction()函数执行完毕后,其执行环境的作用域链会被销毁,但其活动对象不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。
  • 直到匿名函数被销毁后,createComparisonFunction()的活动对象才会被销毁。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function createComparisonFunction(propertyName){
returne function( object1, object2){
var value1 = boject1[propertyName];
var value1 = boject1[propertyName];

if(value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
}
}
//创建函数,并调用函数。
var compareNames = createComparisonFunction("name");
var result = compareNames({name:'liming'},{name:'zhao'});
//接触对匿名函数的引用,以便释放内存
compareNames = null;
  • 注意。闭包只能取得包含函数中任何变量的最后一个值,因为闭包所保存的是整个变量对象。
  • 在闭包中使用this对象很可能会出问题,this可能指向window。
  • 内存泄露。闭包中不使用包含函数的对象,会造成其占用的内存永远不会被回收。在包含函数中,使用的对象,最后设置为null。收回对象占用的大量内存。

模仿块级作用域

创建并立即调用一个函数,这个既可以执行其中的代码,又不会再内存中留下对该函数的引用,这就是模仿块级作用域。一般用于限制向全局作用域中添加过多的变量和函数。

1
2
3
4
5
6
7
8
9
function outputNumbers(count){
(function(){
for(var i=0; i < count; i++){
alert(i);
}
})();

alert(i); //会导致错误
}

私有变量

严格来说,JavaScript中没有私有成员的概念。不过任何在函数中定义的变量,都可以认为是私有变量。利用私有和特权成员,可以隐藏那些不应该被直接修改的数据。例如:

1
2
3
4
5
6
7
8
function Person(name){
this.getName = function(){
return name;
}
this.setName = function(value){
name = value;
}
}