什么是 JavaScript的閉包?用大白話來解釋一下(一)

原文鏈接:What's a JavaScript closure? In plain English, please.

JavaScript里的每一個(gè)函數(shù)都擁有閉包,這是 JavaScript 這個(gè)語言最酷的特性之一。因?yàn)槿绻麤]有閉包,要實(shí)現(xiàn)像回調(diào)或事件處理器這樣的通用結(jié)構(gòu)是很困難的。

無論何時(shí),只要你聲明了一個(gè)函數(shù),你就創(chuàng)造了一個(gè)閉包。當(dāng)你執(zhí)行這個(gè)函數(shù)的時(shí)候,這些閉包能使函數(shù)在它的作用域內(nèi)讀取那些數(shù)據(jù)。

這有點(diǎn)像汽車在被生產(chǎn)(定義)出來的時(shí)候就設(shè)置了一些函數(shù),比如startaccelerate、decelerate。這些函數(shù)會在駕駛員(the driver)每次啟動這輛汽車的時(shí)候被調(diào)用。這些函數(shù)的閉包由這輛車本身來定義,它們可以使外部的函數(shù)無法讀取函數(shù)內(nèi)部的數(shù)據(jù)。

讓我們把這個(gè)類比具象到accelerate這個(gè)函數(shù)里。這個(gè)函數(shù)在汽車被制造的時(shí)候被定義。

function accelerate(force){
  //汽車啟動了嗎?
  //汽車還有油嗎?
  //我們是否處于牽引力控制模式?
  //很多其他的檢查......
  //如果一切順利,油耗取決于動力變量(我們有多用力去踩油門)
}

駕駛員每次踩下油門,這個(gè)函數(shù)就會執(zhí)行。請注意,此函數(shù)如何需要訪問很多變量才能運(yùn)行,包括其自身的force變量,但更重要的事,它需要其他 car 函數(shù)控制的外部變量。這就是accelerate函數(shù)的閉包(我們從汽車本身得到)派上用場的地方。

這就是accelerate函數(shù)的閉包如何運(yùn)用于accelerate函數(shù)本身:

好,“加速”,當(dāng)你執(zhí)行這個(gè)函數(shù),你可以獲取到force這個(gè)變量,你可以獲取到isCarStarted變量,你也可以獲取到fuelLevel變量,還有isTractionControlOn變量。你也可以控制我們傳給發(fā)動機(jī)的currentFuelSupply變量。

需要注意的是,閉包并沒有把這些變量的固定的值傳給accelerate函數(shù),而是給予了一個(gè)“許可”——當(dāng)accelerate函數(shù)執(zhí)行的時(shí)候可以獲取這些變量的值。

閉包和函數(shù)作用域密切相關(guān),因此理解函數(shù)作用域是如何運(yùn)作的將有助于你理解閉包。簡而言之,要理解作用域最重要的是理解當(dāng)你執(zhí)行函數(shù)的時(shí)候,一個(gè)私有的作用域就被創(chuàng)建了,這個(gè)作用域就是用于執(zhí)行這個(gè)函數(shù)。

然后當(dāng)你在函數(shù)里執(zhí)行其他函數(shù)時(shí),這些函數(shù)作用域還會互相嵌套(你會經(jīng)常這樣做的)。

當(dāng)你定義一個(gè)函數(shù)的時(shí)候,閉包就被創(chuàng)建出來了——而不是在你執(zhí)行的時(shí)候。這樣一來,每次你執(zhí)行那個(gè)函數(shù),早已被你創(chuàng)建的那個(gè)閉包使它可以訪問所有可以訪問的函數(shù)作用域。

在某種程度上,你可以認(rèn)為作用域是臨時(shí)的(全局作用域是惟一的例外),而閉包本身是永久的。

為了能夠真正地理解閉包和它在 JavaScript 中所起的作用,你首先需要理解關(guān)于 JavaScript 函數(shù)和它的作用域的一些簡單的概念。

(未完待續(xù))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容