http://edu.51cto.com/lesson/id-6389.html
匿名函数:没有名字的函数。
闭包:
闭包是建立在一个匿名函数里面的。
闭包是指 有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式, 是在一个函数内部创建另一个函数,建议非必要时, 不要使用闭包,匿名函数也是差不多。
即,闭包是一个函数,是能够访问别的函数作用域变量的函数,那么内部函数肯定能访问外部函数的变量,但是外部函数不能访问内部函数的变量(外部函数不能访问局部变量) ,若想实现这种访问,此时就用到了匿名函数 ( 闭包 )。所以闭包和匿名函数是什么关系呢?是包含关系,即闭包肯定是个匿名函数。
一、匿名函数
1.普通函数
function box(){
return 'lee';
}
alert(box()); //输出 lee
2.匿名函数
function (){
return 'lee';
} //单独的匿名函数,无法运行。就算能运行,也无法调用,因为没有名称
3.把匿名函数赋值给变量
var box = function (){
return 'lee';
};
alert(box()); //输出 lee
alert(box);//输出function (){ return 'lee'; }
4.通过表达式自我执行 通过自我执行来执行匿名函数
(匿名函数)(); 第一个圆括号放匿名函数,第二个圆括号执行
(function (){
alert( 'lee');
})(); //输出 lee
5.不用alert 用返回执行
var box = (function(){
return 'lee';
})();
alert(box); //输出 lee 把匿名函数自我执行的返回值赋值给变量 区别与3.把匿名函数赋值给变量
6.自我执行后 用alert打印
alert((function(){
return 'lee';
})());//输出 lee
7.自我执行匿名函数的传参
(function(age){
alert(age);
})(100);//在100的位置传参
二、闭包
1.函数里放一个匿名函数
function box(){
return function(){ //闭包 函数里的函数
return 'lee';
}
}
alert(box);
//输出
function box(){
return function(){
return 'lee';
}
}
alert(box());
//输出
function(){
return 'lee';
}
alert(box()());
//输出 lee
2.上述函数的另一种调用
var b = box();
alert(b()); //输出lee
以上1 2 为铺垫,以下正式进入闭包
闭包:是指有权访问另一个函数(如b函数)作用域中的变量的函数(如a函数),创建闭包的常见的方式就是在一个函数(b)内部创建另一个函数(a),通过另一个函数(a)访问这个函数(b)的局部变量。简单来讲,在b函数里创建a函数,a就是闭包,我们可以通过a函数来访问b函数的局部变量。
3.通过闭包可以返回局部变量
function box(){
var age = 100;
}
alert(age);// 报错:age is not defined 因为age是私有的局部变量 外面访问不到 若在函数里面加上 return age;外部可以访问,但是这和闭包没有关系。
以下为正确的 通过闭包返回局部变量
function box(){
var age = 100;
return function(){
return age;
};
}
alert(box()());//输出100
4.经典的例子 累加
使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,命名冲突,每个模块都可调用必将引来灾难,所以推荐使用私有的,封装的局部变量)。
普通函数的局部变量,调用的时候会存在内存中一会儿,调用完毕,则从内存自动销毁。若使用闭包,可以把局部变量驻留在内存中。
//使用全局变量进行累加
var age = 100;
function box(){
age++;
}
alert(age); //输出100
box();
alert(age);//输出101
box();
alert(age);//输出102 以上实现累加
//使用局部变量进行累加
function box(){
var age=100;
age++;
return age;
}
alert(box());//输出101
alert(box());//输出101 因为每次调用box(),都会初始化age=100
//使用匿名函数实现局部变量驻留内存中从而累加 (真正要讲的是这个)
function box(){
var age=100;
return function(){
age++;
return age;
}
}
var b = box();
alert(b());//输出101
alert(b());//输出102
alert(b());//输出103
如果按照下面的调用,则不能实现累加
alert(box()());//输出101
alert(box()());//输出101 这样调用还是会初始化的。
这里访问不到局部变量age
alert(age);// not defined
PS:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存,过度使用闭包会导致性能下降,建议在非常必要的时候才使用闭包。
function box(){
var age=100;
return function(){
age++;
return age;
}
}
var b = box();
alert(b());//输出101
alert(b());//输出102
alert(b());//输出103
alert(b);//输出函数,b会一直驻留在内存中,打印b,它就是 function(){age++; return age;}
b = null; //最后不用了,解除引用,等待垃圾回收
alert(b);//b is not a function