Javascript 的闭包

1. 闭包的概念

据咱们所知,局部变量在函数退出以后就不占据内存空间,但存在一种特殊的函数,能使局部变量在函数退出以后继续占据内存,为外部函数所调用,这个特殊的函数就是闭包。那么闭包是怎么作到将局部函数一直占据内存的呢?看看下面的例子。闭包

function a(){
    var Aitem=2;//定义局部变量item
    function b() { //定义内部函数b()
        alert(Aitem);
    }
    b();
}
a();//结果是2
复制代码

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


3. 总结

闭包是能够读取其余函数内部变量的函数,是外部函数和内部函数的一座桥梁。内存

闭包拥有两个做用:作用域

  • 使局部变量keep alive
  • 读取其余函数的局部变量

闭包的缺点:it

  • 常驻内存,形成内存的浪费
相关文章
相关标签/搜索