什么是闭包?
广义上讲,function都是闭包,不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”。
先看一个例子
function a(){
var num=1;
var b=function(){
console.log(num)
}
return b;
}
a()();
以上就是闭包,也就是你把当函数作为返回值,并且函数b对a中的变量保持着引用,这时候,变量num不会得到释放,当执行b函数的时候就形成了闭包
需要注意的是:
函数b如果没有引用函数a的变量,只是return,将不存在闭包。
闭包的作用
- 在函数外部能访问函数内部的变量。
- 使变量始终保存在内存当中,不被垃圾机制回收。
- 封装,对外只暴漏接口。
第一条,如文章开头例子。
第二条,也是最重要的一条,讲之前,先讲一下JavaScript的垃圾回收机制 。
在Javascript中,如果一个变量不再被引用,那么这个变量就会被GC回收。如果一个变量被在另外一个作用域引用,而不再被第3者所引用,那么执行完后,变量还是会被GC回收。如果函数a的变量被函数b引用,函数b又被函数a外的函数c引用,那么函数a执行完后变量就不会垃圾回收机制回收。
这时候回过头看这个例子
function a(){
var num=1;
var b=function(){
num++;
console.log(num)
}
return b;
}
var c=a();
c();//2
c();//3
num在函数b中引用,而函数b又被函数c引用,三层引用,这个时候,就不会被GC回收,函数a的变量就会始终保存在函数变量当中。
从控制台可以看出来,当运行c的时候,a已经形成了闭包,closure就是闭包的意思。
第三条,封装
function Fn3(type){
var name='hty';
var sex='男';
return {
type:type,
handle(){
console.log(name+"是"+sex);
}
}
}
var fn3=new Fn3("封装");
console.log(fn3);
再控制台可以看出,只能访问到函数暴漏的属性和方法,从而保护了函数的私有属性或私有方法。
总结
以上就是本人对闭包的理解,如有不对地方,还望指出,另外提醒大家,由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。