据咱们所知,局部变量在函数退出以后就不占据内存空间,但存在一种特殊的函数,能使局部变量在函数退出以后继续占据内存,为外部函数所调用,这个特殊的函数就是闭包
。那么闭包是怎么作到将局部函数一直占据内存的呢?看看下面的例子。闭包
function a(){
var Aitem=2;//定义局部变量item
function b() { //定义内部函数b()
alert(Aitem);
}
b();
}
a();//结果是2
复制代码
从上能够看出内部函数能够读取外部函数的局部变量。此时的内部函数的做用域仅限于外部函数a(),只有经过调用外部函数a()才能够运行内部函数b()。当外部函数执行结束,内部函数的内存也将清除。可是若是咱们将内部函数赋给一个全局变量
,那么内部函数将从局部变量
转化成全局变量
。即便外部函数退出了,做为全局变量的内部函数也将保存在内存中。那么如何让内部函数成为全局变量呢?函数
function a(x){
var Aitem=2;//定义局部变量item
return function b(y) { //a函数结果返回一个b函数
alert(x+y+(++Aitem));
}
}
var closure=a(1);//将a(1)return的结果b()赋给全局变量,closure=b(y){ alert(1+y+(++Aitem))}
closure(1);//弹出5;closure(1)=b(y){ alert(1+1+(++2))}
closure(1);//弹出6;closure(1)=b(y){ alert(1+1+(++3))}
复制代码
上例中的closure()函数即闭包
。第一次closure(1)中Aitem=2
,第二次closure(1)中Aitem=3
,能够看出item
这个局部变量在a()退出之后并无被清除,而是像一个全局变量同样一直保存在内存中。这就是闭包的神奇所在。closure()闭包依赖于b(y),而b(y)又是a(x)的局部函数,故closure()闭包能够实时访问a(x)的局部变量。若是没有将内部函数装化成全局变量的话,就形不成闭包,请看下面的例子:spa
function a(x){
var Aitem=2;//定义局部变量item
function b(y) { //定义局部函数b
alert(x+y+(++Aitem));
}
b(1);//在a()内部运行b(1);即alert(x+1+(++2))
}
a(1);//弹出5;即alert(1+1+(++2))
复制代码
上例没有将局部函数b()赋给全局变量,在a(1)运行之后b()就不复存在,Aitem也无从获取。code
闭包是能够读取其余函数内部变量的函数,是外部函数和内部函数的一座桥梁。内存
闭包拥有两个做用:作用域
闭包的缺点:it