闭包的理解

80 阅读2分钟

闭包是什么?当有函数嵌套时,内部函数可以访问外部函数的变量,举个例子:

function foo() {
    let count = 0
    return function inner() {
        return count++
    }
}
let instance = foo()
console.log(instance()) //输出0
console.log(instance()) //输出1
console.log(instance()) //输出2

可以发现我们的函数变得“有状态”了,有了存储功能。如果一个函数是纯函数,那么每次传入相同的参数,输出的内容也应该是一样的,这在很多前端框架里都有应用,可以让代码运行你想要的结果,就像假如你每天都去一个餐馆吃10块钱的饭2荤2素,第二天去你给10块钱老板还应该给你2荤2素,你不希望某天你去餐馆,你给了相同的10块钱,结果老板给了你一棍子,打得你鼻青脸肿。你不知道哪里出了问题,想看看发生了什么,又递给老板10块钱,他给了你2荤2素,之后几天你多次实验,发现给10块钱,老板大部分情况给你2荤2素,偶尔给你一棍子,这种事情反复发生之后,你就会换一家吃饭了。
所以一般来说我们希望每次给同样的参数,返回的值应该是一样的,应该是无状态的。而闭包不这样,它的原理是在内层函数有一个词法环境,保存了外部函数的变量,从而导致在外部函数结束了之后,内部函数还没有被垃圾回收,运行之后会更新并保存状态。
我们可以利用闭包的特性实现防抖和节流。在Vue2响应式原理中也用到了闭包来实现数据的变化检测:

function defineReactive(target, key, value) {
    Object.defineProperty(target, key, {
        get() {
            return value
        },
        set(newValue) {
            if(newValue === value) return
            value = newValue
        }
    })
}