blog icon indicating copy to clipboard operation
blog copied to clipboard

JS闭包是什么

Open BlingSu opened this issue 4 years ago • 0 comments

  1. 什么是「闭包」
  2. 「闭包」的作用是什么?

什么是闭包

(function () {
  var local = 'variable' //在函数内部可以访问的变量
  function foo () { // 函数
    console.log(local)
  }
})()

上述三行代码在一个立即执行函数中,这里有一个局部变量local,有一个函数foo,foo里面可以访问到local变量,这就是一个闭包。

「函数」和「函数内部可以访问到的变量」(也叫环境)的总和,就是一个闭包

再来看看嵌套函数的情况

function foo () {
  var local = 1
  function bar () {
    local++
    return local
  }
  return bar
}
var func = foo()
func()

这里就有一个闭包啦,local变量和bar函数就组成了一个闭包。

为什么要函数嵌套函数?

因为我们在某些特定的时候是需要局部变量的,所以才把local放在一个函数里面,如果不把local放在一个函数里面,local就相当于是一个全局变量,那么就达不到闭包的目的(隐藏变量)。所以说,函数嵌套函数其实就是为了造出一个局部变量而已,和闭包没有关系。

为什么要return bar?

如果不return,这里就没办法使用这个闭包,把return bar改成window.bar = bar也是一样的,只要让外面可以访问到这个bar函数就可以了,所以说return bar只是为了bar能被使用,也跟闭包没有关系。

闭包的作用

通俗点说就是,间接访问一个变量,换句话说,就是隐藏一个变量。

假设我们在写一个游戏,在写其中关于还剩下几条命的代码,假设不用闭包,那么可以直接用一个全局变量

window.lives = 3 // 还有三条命

只要乍一看没毛病,但是仔细一想如果不小心改了这个值变成-1了怎么办,所以不能让别人可以直接访问到这个变量,所以就要用局部变量,但是问题又来了,局部变量别人又访问不到咋办呢?这里可以暴露一个函数,让别人间接的去访问。

!(function () {
  var lives = 5
  window.addLives = function () {
    lives += 1
  }
  window.cutLives = function () {
    lives -= 1
  }
})()
  • 这里lives + addLives 或者 cutLives 就是变量+函数 = 闭包

再来看看最开始的代码

(function () {
  var local = 'variable' //在函数内部可以访问的变量
  function foo () { // 函数
    console.log(local)
  }
})()

闭包是JS函数作用于的副产品。也可以这么理解,由于JS的函数内部可以使用函数外部的变量,所以这个代码正好符合了闭包的定义罢了。

注意

闭包不会造成内存泄漏。内存泄漏是指用不到(或者访问不到)的变量,依然占据的内存空间,不会再次利用起来。闭包里面的变量明明是我们需要的变量(比如上面的lives),所以说不是内存泄漏。当然IE时代,IE在闭包用完的时候,依然不会回收闭包里面引用的变量,这是IE的问题,不是闭包的问题。

BlingSu avatar Nov 06 '20 12:11 BlingSu