1. 闭包的定义
闭包是指有权访问另一个函数作用域中的变量的函数.
2. 闭包的常见表现形式
- 在函数中返回一个函数
- 立即调用匿名函数(IIFE)
3. 闭包涉及的特性
3.1 垃圾回收机制
JavaScript 的垃圾回收机制是自动回收, 回收的标准是只要一个变量在内存中还存在着引用, 那么该变量就不会被垃圾回收机制回收, 会一直存在于内存中.
这个是闭包存在的前提.
3.2 作用域
JavaScript中, 作用域有4种, 大括号作用域, for 循环括号作用域, 函数作用域, 全局作用域
- 大括号作用域
- for 循环括号作用域
- 函数作用域
- 全局作用域
这里特别说一下for 循环括号作用域: for 循环中的括号存在着一个单独的作用域, 如下代码所示
for (let i = 0; i < 5; i++) {
let i = 'here'
console.log(i)
}
// here
// here
// here
// here
// here
3.3 作用链域
作用链域是JavaScript 变量的访问机制, 它表示当访问一个变量时, 我们会现在当前作用域寻找, 如果没有找到相对应的变量, 那么根据作用链域的嵌套依次向上寻找, 直到全局作用域
4. 闭包理解
只要内存中存在着函数中变量的引用, 那么该函数就会一直存在于内中,不会被垃圾回收机制清理, 而且该函数的变量能够在作用链域的作用下被访问到
5. 闭包优势和局限
5.1 优势
- 消除全局变量
- 使变量存在于内存中, 使其能被访问到, 同时保存还可以保存对变量操作的结果
5.2 闭包造成的问题
- 由于闭包会使函数一直存在于内存中, 可能造成内存泄漏
6. demo
function counter(number=0) {
let result = number
function caculate() {
result++
return result
}
return caculate
}
let a = counter(10)
let b = counter()
a() // 11
a() // 12
b() // 1