blog
blog copied to clipboard
JS闭包是什么
- 什么是「闭包」
- 「闭包」的作用是什么?
什么是闭包
(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的问题,不是闭包的问题。