闭包
闭包实际上是一个很简单的东西,它的存在是为了产生一个私有的局部变量。
局部变量只能用于定义它函数内部。对于其他的函数或脚本代码是不可用的。
全局和局部变量即便名称相同,它们也是两个不同的变量。修改其中一个,不会影响另一个的值。
举个例子,比如你需要一个变量gold,用来记录你有多少金币,你可以直接在window中记录
Window.gold = 100
但是这样有可能会被别人不小心修改,或者因为重名而被覆盖。那咋办呢?
先看一个简单的例子:
let gold = 100
function getGold(){
console.log(gold)
}
这里实际上就是一个最简单的闭包概念:一个局部变量gold,一个函数getGold,函数getGold内部能访问到局部变量gold。
「函数」和「函数内部能访问到的变量」的总和,就是一个闭包。
这里将例子完整一下,做一个增加金币的操作:
function addGold(){
let gold = 100
return funciton(){
gold += 100
console.log(gold)
}
}
let foo = addGold()
foo() // 200
这样gold就是一个函数里的局部变量,并且能在外层通过foo对内部值进行修改和读取。
这里因为let foo = addGold()
这行代码,局部变量gold已经进行了初始赋值,并且存在在内存中,后续调用的函数是return回来的函数,所以不会重置gold的值。
并且如果我增加一个变量bar,私有局部变量gold也是各自独立的:
function addGold(){
let gold = 100
return funciton(){
gold += 100
console.log(gold)
}
}
let foo = addGold()
let bar = addGold()
foo() // 200
foo() // 300
bar() // 200 与foo的各自独立计算
注意,闭包里的私有变量是不会自动回收的,因为返回的函数foo里面有对其变量的gold的引用,此时变量还会被用到,需要在使用完后手动设置为null。
foo = null
bar = null