闭包的定义

闭包是指一个函数有权访问另一个函数作用域中的变量时,这个函数和函数内部能访问到变量的总和。

创建闭包的最常见的方式就是在一个函数内创建另一个函数。

创建的函数可以访问到外部函数的局部变量。

闭包的作用

闭包常常用来间接访问一个变量。换句话说就是隐藏一个变量。

假设我们在做一个游戏,在写其中关于「还剩几条命」的代码。

如果不用闭包,你可以直接用一个全局变量:

window.lives = 30 // 还有三十条命

这样看起来很不妥。万一不小心把这个值改成 -1 了怎么办。所以我们不能让别人「直接访问」这个变量。怎么办呢?

用局部变量。

但是用局部变量别人又访问不到,怎么办呢?

暴露一个访问器(函数),让别人可以「间接访问」。

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
!function(){

  var lives = 50

  window.奖励一条命 = function(){
    lives += 1
  }

  window.死一条命 = function(){
    lives -= 1
  }

}()

简明起见,我用了中文 :)

那么在其他的 JS 文件,就可以使用 window.奖励一条命() 来涨命,使用 window.死一条命() 来让角色掉一条命。

过使用闭包,可以通过在外部调用闭包函数,从而在外部访问到函数内部的变量,可以使用这种方法来创建私有变量,也就是上文的隐藏一个变量。

闭包的另一个用途是使已经运行结束的函数上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以这个变量对象不会被回收。

闭包的优缺点

优点:

  • 变量长期驻扎在内存中避免全局变量的污染
  • 可以用来定义私有属性和私有方法

缺点:

  • 常驻内存会增大内存的使用量
  • 使用不当会造成内存泄露,但是这是因为IE 有 bug,IE 在我们使用完闭包之后,依然回收不了闭包里面引用的变量。这是 IE 的问题,不是闭包的问题。参见司徒正美的这篇文章