Javascript中闭包是一大难点,但又绕不过去。
之前我们已经谈到过Javascript语言独特作用域,在谈论闭包时,我们仍要继续谈到它。和其它很多语言一样,函数内部的变量对于函数外部是不可见的。反过来函数外部变量,比如全局变量对于函数内部来说是可见的。前提是没有发生在作用域那一节中遇到的变量提升问题。
不过Javascript有一种特殊的函数定义方式:
function f1(){
var n=999;
function f2(){
alert(n); // 999
}
}
在上面的代码中,f1的局部变量在f2函数中实际上是可见的。这就是Javascript的“链式作用域”。即看到一个变量名时,对象会一层层向上寻找所有父对象中的这个变量。所以对于子对象而言,所有父对象的变量都是可见的,反之则不行。
如果我们将f2函数作用f1函数的返回值,这样不就变相的得到了f2的内部变量了。
function f1(){
var n=999;
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
这个实际上就是闭包。可以理解为它将内部函数与外部函数连接在了一起。
function f1(){
var n=999;
nAdd=function(){n+=1}
function f2(){
alert(n);
}
return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000
result实际上就是闭包f2函数。并且我们可以发现f1一直保存着局部变量的值。
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包。解决方法是,在退出函数之前,将不使用的局部变量全部删除。