也许你在很多前端面试中都被问及闭包是什么?闭包有什么作用?闭包有什么弊端?但是你真的理解闭包吗?闭包确实对于初学者来说要理解他有些困难,它主要是属于作用域链的问题,下面就由我带领你学习一下或者理解一下JavaScript的闭包。
1、作用域
我们可以将闭包简单的理解为函数内的函数,首先我们来看一个作用域的示例
[cc lang=”javascript”]function Fn(){
var a = 3;
}
console.log(a); // 此处是报错了,因为我们在函数外部是无法获取函数内部的变量的[/cc]
那么我们可以将上面的函数修改为如下的函数即可得到a的值
[cc lang=”javascript”]var a = 5;
function Fn(){
var a = 3;
return a;
}
consolog.log(a); //返回5
Fn(); //返回 3[/cc]
2、闭包(函数作为返回值)
假如我们想要进行一个相应的计算后,直接输出相应的结果,那么我们就可以直接使用闭包的方式,代码如下
[cc lang=”javascript”]function Fn(){
var a = 3;
function FnAdd(){
return a + 1
};
return FnAdd;
}
Fn(); //返回 4[/cc]
上面的这个例子就是一个实际常用的闭包,我们在函数内部将内部函数return出去,就可以获得函数内部计算的结果。
3、闭包(函数作为参数传递)
除了上面这种函数作为返回值的方法,闭包还可以将函数作为参数传递,示例如下:
[cc lang=”javascript”]var a = 10;
Fn = function(num){
if(num > a){
console.log(x);
}
}
(function(f){
var a = 20;
f(60)
})(Fn)[/cc]
以上示例中,我们可以看到虽然我们再匿名函数中再次指定了a的值,但是我们使用的f(60)传递到Fn中的60与a进行比较,f(60)所比较的a的值应该是10,而并不是匿名函数中的a = 20,我们可以简单的将上面的示例重写成如下,以帮助你更好的理解。
[cc lang=”javascript”]function Fn(){
var a = 10
return function(num){
if(num > a){
console.log(x);
}
}
var f = Fn();
var a = 20;
f(60)[/cc]
4、闭包的用途(优点)
1)、可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
2)、逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑而单独编写额外逻辑。
5、闭包的缺点
1)、由于闭包会将返回值或者变量值保存在内存中,使用不当会引起内存泄漏的问题,从而导致浏览器奔溃。所以不能滥用闭包。解决方法是,在退出函数之前,将不使用的局部变量全部删除
比如上面第三点提到的示例:
[cc lang=”javascript”]var a = 10;
Fn = function(num){
if(num > a){
console.log(x);
}
}
(function(f){
var a = 20;
f(60)
})(Fn)[/cc]
为了防止内存泄漏,我们在获得结果后,我们要讲相应的变量从内存中释放出来,那么久用到了null,我们可以将上面的代码改为如下即可
[cc lang=”javascript”]var a = 10;
Fn = function(num){
if(num > a){
console.log(x);
}
}
(function(f){
var a = 20;
f(60)
})(Fn)
Fn = null
[/cc]
2)、闭包会在父函数外部,改变父函数内部变量的值。如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便