什么是闭包?相信很多人听了有点懵,然后去百度查了一下官方的定义“闭包就是能够读取其他函数内部变量的函数”发现感觉自己更懵了。关于闭包如果只看那官方的定义的话确实不是让人很容易理解。
要想理解什么是闭包,首先得弄清楚什么是作用域,作用域可以理解为一个变量可以使用的范围。
在 JAVAScript 中有两种作用域类型:
在 JavaScript 函数中声明的变量会成为函数的局部变量。局部变量的作用域是局部的所以只能在函数内部访问它们。
函数外声明的变量属于全局变量。全局变量的作用域是全局的所以网页的任意部分和函数都能够访问它。
有了作用域做铺垫,再来学习闭包就容易多了。
function f1(){
var n=10;//局部变量n
//在f1函数内部声明的f2函数
function f2(){
alert(n);
}
return f2;//将f2函数作为f1函数的返回值
}
var fobj=f1();//f1调用完后的返回值是一个f2函数,此时fobj就是f2函数
fobj(); // 输出10,调用f2函数
上述代码就是一个简单的闭包函数,闭包的用处有两个,一个是可以读取函数内部的变量,另一个就是在内存中让这些变量的值始终保持。
function f1(){
var n=5;//局部变量n
add=function(){ //fdd前面没有使用var关键字,因此add是一个全局变量的匿名函数
n+=1
}
//在f1函数内部声明的f2函数
function f2(){
alert(n);
}
return f2;
}
var fadd=f1();
result(); // 输出5
add();
fadd(); // 输出6
从上面这段代码中可以看出,fadd就是闭包f2函数。它一共运行了两次,第一次的值是5,第二次的值是6。这证明函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。因为f1是f2的父函数,而f2相当于赋给了f1一个全局变量,所以f2一直在内存中。而f2的存在又依赖于f1,因此f1也一直在内存中,不会在调用结束后回收。
由于闭包会使函数中的变量都被保存在内存中,导致内存消耗很大,造成网页的性能问题,在IE中还可能导致内存泄露,所以不能滥用闭包,在退出函数之前,将不使用的局部变量全部删除。