闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用域)执行完毕,里面声明的变量会全部释放,被垃圾回收器回收。但闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。
函数内部可以读取函数外部定义的全局变量,
但是函数外部无法读取函数内的局部变量。
闭包就是能够读取其他函数内部变量的函数,函数没有被释放,整条作用域链上的局部变量都将得到保留。
由于在javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成‘定义在一个函数内部的函数’。
举例说明:
function f1(){
n = 999;
function f2(){
console.log(n);
}
return f2;
}
var result = f1(); //返回的是f2函数
result(); //999
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 现在是一个闭包
bar(10);
在foo中,声明一个变量tmp,他属于foo作用域下的变量。函数返回一个函数,这个函数被嵌套,函数内部弹出x+y(++tmp)。,首先执行var bar = foo(2);那么foo就执行了,参数2也传进去了,但是执行完毕之后,tmp变量以及参数x就已经被释放回收了吗?并没有,因为返回值里面还等待使用这些变量,所以此时,foo虽然执行了,但是foo的变量并没有被释放,在return在等待继续使用这些变量了,这个时候bar就是一个闭包。
然后我们再执行bar,结果是16,