輕鬆介紹閉包的主題,這是理解 JavaScript 函數如何運作的關鍵。
如果你曾經在 JavaScript 中寫過函數,你已經使用過閉包了。
這是一個需要理解的重要主題,會對你能做的事情產生影響。
當一個函數被執行時,它是在定義時的作用域中運行,而不是在執行時的狀態中運行。
作用域基本上是一組可見的變數。
一個函數記住了它的詞法作用域,它能夠訪問在父範圍中定義的變數。
簡而言之,一個函數能夠訪問一個完整的變數集合。
讓我馬上舉個例子來澄清這點。
const bark = dog => {
const say = `${dog} barked!`
;(() => console.log(say))()
}
bark(`Roger`)
這將按預期將 Roger barked!
輸出到控制台。
如果你想返回這個動作呢:
const prepareBark = dog => {
const say = `${dog} barked!`
return () => console.log(say)
}
const bark = prepareBark(`Roger`)
bark()
這段代碼也會在控制台上輸出 Roger barked!
。
讓我們舉一個最後的例子,它使用 prepareBark
預先設定兩隻不同的狗:
const prepareBark = dog => {
const say = `${dog} barked!`
return () => {
console.log(say)
}
}
const rogerBark = prepareBark(`Roger`)
const sydBark = prepareBark(`Syd`)
rogerBark()
sydBark()
這段代碼將輸出:
Roger barked!
Syd barked!
正如你所看到的,變量 say
的狀態與從 prepareBark()
返回的函數相關聯。
同時請注意,我們在第二次調用 prepareBark()
時重新定義了一個新的 say
變量,但這並不會影響第一個 prepareBark()
作用域的狀態。
這就是閉包的工作方式:從 prepareBark()
返回的函數保留了原始狀態。