JavaScript變量可以屬于本地作用域或全局作用域。
可以使用閉包將全局變量設(shè)為局部(私有)。
假設(shè)我們要使用一個(gè)變量來計(jì)數(shù)某物,并且希望該計(jì)數(shù)器可用于所有函數(shù)。
我們可以使用一個(gè)全局變量和一個(gè)增加計(jì)數(shù)器的函數(shù):
// 初始化計(jì)數(shù)器
var counter = 0;
// 遞增計(jì)數(shù)器函數(shù)
function increment() {
counter++;
}
// 調(diào)用increment() 3次
increment();
increment();
increment();
// 現(xiàn)在該計(jì)數(shù)器應(yīng)為3
document.getElementById("output").innerHTML = `計(jì)數(shù)器: ${counter}`;測試看看?/?上面的解決方案存在一個(gè)問題:頁面上的任何代碼都可以更改計(jì)數(shù)器,而無需調(diào)用increment()。
JavaScript內(nèi)部函數(shù)可以解決此問題。
JavaScript支持嵌套函數(shù)。嵌套函數(shù)可以訪問其上方的范圍。
在此示例中,內(nèi)部函數(shù)可以訪問外部函數(shù)中的計(jì)數(shù)器變量:
function outer() {
var counter = 0;
function inner() {
counter++;
}
return counter;
}測試看看?/?嵌套函數(shù)可以解決前面的問題,如果我們可以從外部訪問inner()函數(shù)。
我們還需要找到只執(zhí)行一次counter = 0的方法,那就是下面講到的閉包。
閉包是函數(shù)和聲明該函數(shù)的詞法環(huán)境的組合。
閉包可以從另一個(gè)函數(shù)的作用域訪問變量。這是通過在函數(shù)內(nèi)部創(chuàng)建函數(shù)來實(shí)現(xiàn)的。當(dāng)然,外部函數(shù)無法訪問內(nèi)部作用域。
var increment = (function() {
var counter = 0;
function inner() {
return ++counter;
}
return inner;
})();測試看看?/?為變量增量分配了自執(zhí)行函數(shù)的返回值。
自執(zhí)行功能僅運(yùn)行一次。它將計(jì)數(shù)器設(shè)置為零,并返回函數(shù)表達(dá)式。
閉包是即使父函數(shù)已關(guān)閉,也可以訪問父作用域的函數(shù)。