JavaScript变量可以属于本地作用域或全局作用域。
可以使用闭包将全局变量设为局部(私有)。
为什么我们需要闭包?
假设我们要使用一个变量来计数某物,并且希望该计数器可用于所有函数。
我们可以使用一个全局变量和一个增加计数器的函数:
// 初始化计数器
var counter = 0;
// 递增计数器函数
function increment() {
counter++;
}
// 调用increment() 3次
increment();
increment();
increment();
// 现在该计数器应为3
document.getElementById("output").innerHTML = `计数器: ${counter}`;
上面的解决方案存在一个问题:页面上的任何代码都可以更改计数器,而无需调用increment()。
JavaScript内部函数可以解决此问题。
JavaScript 嵌套函数
JavaScript支持嵌套函数。嵌套函数可以访问其上方的范围。
在此示例中,内部函数可以访问外部函数中的计数器变量:
function outer() {
var counter = 0;
function inner() {
counter++;
}
return counter;
}
嵌套函数可以解决前面的问题,如果我们可以从外部访问inner()函数。
我们还需要找到只执行一次counter = 0的方法,那就是下面讲到的闭包。
JavaScript 闭包
闭包是函数和声明该函数的词法环境的组合。
闭包可以从另一个函数的作用域访问变量。这是通过在函数内部创建函数来实现的。当然,外部函数无法访问内部作用域。
var increment = (function() {
var counter = 0;
function inner() {
return ++counter;
}
return inner;
})();
为变量增量分配了自执行函数的返回值。
自执行功能仅运行一次。它将计数器设置为零,并返回函数表达式。
闭包是即使父函数已关闭,也可以访问父作用域的函数。