Notes for a front-end developer, esyou.net

0%

简简单单理解JAVASCRIPT闭包

也许你在很多前端面试中都被问及闭包是什么?闭包有什么作用?闭包有什么弊端?但是你真的理解闭包吗?闭包确实对于初学者来说要理解他有些困难,它主要是属于作用域链的问题,下面就由我带领你学习一下或者理解一下JavaScript的闭包。

作用域

我们可以将闭包简单的理解为函数内的函数,首先我们来看一个作用域的示例

1
function Fn(){
2
  var a = 3;
3
}
4
console.log(a); // 此处是报错了,因为我们在函数外部是无法获取函数内部的变量的

那么我们可以将上面的函数修改为如下的函数即可得到a的值

1
var a = 5;
2
function Fn(){
3
  var a = 3;
4
  return a;
5
}
6
consolog.log(a); //返回5
7
Fn(); //返回 3

闭包(函数作为返回值)

假如我们想要进行一个相应的计算后,直接输出相应的结果,那么我们就可以直接使用闭包的方式,代码如下

1
function Fn(){
2
  var a = 3;
3
  function FnAdd(){
4
    return a + 1
5
  };
6
  return FnAdd;
7
}
8
Fn(); //返回 4

上面的这个例子就是一个实际常用的闭包,我们在函数内部将内部函数return出去,就可以获得函数内部计算的结果。

闭包(函数作为参数传递)

除了上面这种函数作为返回值的方法,闭包还可以将函数作为参数传递,示例如下:

1
var a = 10;
2
Fn = function(num){
3
  if(num > a){
4
    console.log(x);
5
  }
6
}
7
(function(f){
8
  var a = 20;
9
  f(60)
10
})(Fn)

以上示例中,我们可以看到虽然我们再匿名函数中再次指定了a的值,但是我们使用的f(60)传递到Fn中的60与a进行比较,f(60)所比较的a的值应该是10,而并不是匿名函数中的a = 20,我们可以简单的将上面的示例重写成如下,以帮助你更好的理解。

1
function Fn(){
2
  var a = 10
3
  return function(num){
4
  if(num > a){
5
    console.log(x);
6
  }
7
}
8
var f = Fn();
9
var a = 20;
10
f(60)

闭包的用途(优点)

1)、可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
2)、逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑而单独编写额外逻辑。

闭包的缺点

1)、由于闭包会将返回值或者变量值保存在内存中,使用不当会引起内存泄漏的问题,从而导致浏览器奔溃。所以不能滥用闭包。解决方法是,在退出函数之前,将不使用的局部变量全部删除
比如上面第三点提到的示例:

1
var a = 10;
2
Fn = function(num){
3
  if(num > a){
4
    console.log(x);
5
  }
6
}
7
(function(f){
8
  var a = 20;
9
  f(60)
10
})(Fn)

为了防止内存泄漏,我们在获得结果后,我们要讲相应的变量从内存中释放出来,那么久用到了null,我们可以将上面的代码改为如下即可

1
var a = 10;
2
Fn = function(num){
3
  if(num > a){
4
    console.log(x);
5
  }
6
}
7
(function(f){
8
  var a = 20;
9
  f(60)
10
})(Fn)
11
Fn = null

2)、闭包会在父函数外部,改变父函数内部变量的值。如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便