[JS]什么是闭包()

首先来思考一下下面的案例:

function unclosure() { let count = 0 return count++ }for (let index = 0; index < 10; index++) { let result = unclosure() console.log(result) }

我在函数内实现一个很简单的计数器功能,希望在最后得到一个成功累加之后的数字。unclosure 函数是没有利用闭包写的计数器。
通过 for 的10次循环,打印 result,当我们打开浏览器运行这一段代码之后:
[JS]什么是闭包()
文章图片
unclosure 函数被重复调用了10次,每次的 count 变量都不会成为下一次函数计数时使用的那个 count 变量。也就是说,每次函数重新运行的时候,此 count 变量非上一次 count 变量,所以,对于下一次函数运行时面对的 count 变量初始值为 0。那么,应该如何解决这个问题呢?
一般会想到把 count 变量提到 unclosure 函数体之外,这样做是肯定可以的。实际上,这样的操作已经是在利用闭包了。让我们改造上面的案例:
let count = 0 function unclosure() { return count++ }

一个函数体内引用了外部的变量时,函数就会形成一个闭包。直到这个函数结束运行,闭包也会随之消失。闭包形成一个持续的环境,闭包内的所有资源都将持续存在着,所以,上面的例子会成功进行累加。
如果不把变量提取到函数体外,直接就在函数里面运行也是可以的,应该如何制造一个闭包呢?
函数引用了外部的变量时,就会形成一个闭包。一句这一结论,我们真的可以在第一个案例中制造一个闭包,来解决最先出现的问题。
function closure() { let count = 0 console.log('closure 函数初始化了一次') return function () { return count++ } }let inner = closure() // 得到一个闭包for (let index = 0; index < 10; index++) { let result = inner() console.log(result) }

closure 函数的内部嵌套了一个匿名函数(也可以嵌套有名函数)。相对于匿名函数来说,它引用了外部函数 closure 的变量 count,这就形成了一个闭包了。
【[JS]什么是闭包()】在运行这段代码之前,我们需要得到 closure 函数的闭包(不要重复得到一个新的闭包,因为会初始化这个环境,回到上诉提到的问题)。最后反复执行 inner() 就可以实现累加了。
[JS]什么是闭包()
文章图片

    推荐阅读