声明:本文对闭包的理解是通过学习方应杭老师的文章,结合个人理解得来的。
【函数】和【函数内部能访问到的变量】的总和,就是一个闭包。
最常见的方式:函数嵌套函数。
function foo() {
var local = 1
function bar() {
local++
return local
}
return bar
}
如上述代码,【函数】bar和【函数内部能访问到的变量】local综合起来就成了一个闭包。函数嵌套函数是为了定义一个局部变量,这个局部变量原本只能在所属函数及所属函数的子函数内使用,但是有时候外部函数也想要使用这个局部变量,此时就会使用函数嵌套的方式,利用JavaScript的作用域链,即子函数可以使用父函数中定义的局部变量,然后返回这个子函数,就可以让外部函数使用foo函数中的局部变量local了。
function foo() {
var local = 1
function bar() {
local++
return local
}
return bar
}
var func = foo()
console.log(func)
//输出结果
//ƒ bar() {
// local++
// return local
// }
console.log(func())
//输出结果
//2
如上述代码,外部用func去使用foo函数内的局部变量。这里需要将子函数bar作为父函数foo的返回值,这样才能在调用func()时调用bar函数,得到local的值。
闭包的作用
常用于:
1、间接访问一个变量
当外部函数想使用本函数内部的局部变量时,我们可以在本函数中设置一个接口,也就是一个函数,例如上述的bar函数,让外部函数可以间接使用。这个bar函数就相当于外部函数和bar函数的父函数foo之间的桥梁。
2、隐藏一个变量
比如外部函数func使用了foo函数中的变量local,但就func函数而言,只知道结果,不知道使用了什么变量。
3、可以用来保存一个需要长期保存的变量
闭包的环境相对封闭,不容易被污染,并且闭包内的变量会一直在内存中,所以可以用来保存长期需要的变量。但是不能保存占内存太大的东西吧,不然太耗内存了,影响性能。
闭包中使用的局部变量会保存在内存中
function fn(){
var x = 1
return function(){
var y = 1
console.log(++x)
console.log(++y)
}
}
var func = fn()
console.log(func()) //输出2 2
console.log(func()) //输出3 2
如上述代码,第三行是一个匿名函数,该匿名函数是fn的返回值。由于func一直存在于内存中,它依赖于fn函数,则fn函数也会一直保存在内存中,所以第二次调用func时,x的值是3而不是2,因为fn函数没有被垃圾回收机制清除,保存了x的状态,但是y会每次重新定义,所以每次会销毁,下次运行时再创建。
会导致内存泄露问题
以上是我的理解,小菜鸟一个,可能存在错误,恳请大家指正!