Day23:繼續(xù)閉包的故事

【書名】:你不知道的JavaScript(上卷)

【作者】:Kyle Simpson

【本書總頁(yè)碼】:213

【已讀頁(yè)碼】:63

function\ wait(message)\ \left\{\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\         setTimeout( function\ timer()\ \left\{\\             console.log( message );\ \ \ \ \ \ \\ \right\},\ 1000 );\right\}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\\ \\wait( "Hello, closure!" );\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

將一個(gè)內(nèi)部函數(shù)(名為 timer)傳遞給 setTimeout(..)。timer 具有涵蓋 wait(..) 作用域的閉包,因此還保有對(duì)變量 message 的引用。

wait(..) 執(zhí)行 1000 毫秒后,它的內(nèi)部作用域并不會(huì)消失,timer 函數(shù)依然保有 wait(..)作用域的閉包。

深入到引擎的內(nèi)部原理中,內(nèi)置的工具函數(shù) setTimeout(..) 持有對(duì)一個(gè)參數(shù)的引用,這個(gè)參數(shù)也許叫作 fn 或者 func,或者其他類似的名字。引擎會(huì)調(diào)用這個(gè)函數(shù),在例子中就是內(nèi)部的 timer 函數(shù),而詞法作用域在這個(gè)過(guò)程中保持完整。

這就是閉包。

本質(zhì)上無(wú)論何時(shí)何地,如果將函數(shù)(訪問(wèn)它們各自的詞法作用域)當(dāng)作第一級(jí)的值類型并到處傳遞,你就會(huì)看到閉包在這些函數(shù)中的應(yīng)用。在定時(shí)器、事件監(jiān)聽器、Ajax 請(qǐng)求、跨窗口通信、Web Workers 或者任何其他的異步(或者同步)任務(wù)中,只要使用了回調(diào)函數(shù),實(shí)際上就是在使用閉包!

var a = 2;\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\\ \\(function\ IIFE()\ \left\{\\console.log( a );\\\right\})();\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \

雖然這段代碼可以正常工作,但嚴(yán)格來(lái)講它并不是閉包。因?yàn)楹瘮?shù)IIFE并不是在它本身的詞法作用域以外執(zhí)行的。它在定義時(shí)所在的作用域中執(zhí)行(而外部作用域,也就是全局作用域也持有 a)。a 是通過(guò)普通的詞法作用域查找而非閉包被發(fā)現(xiàn)的。

盡管 IIFE 本身并不是觀察閉包的恰當(dāng)例子,但它的確創(chuàng)建了閉包,并且也是最常用來(lái)創(chuàng)建可以被封閉起來(lái)的閉包的工具。因此 IIFE 的確同閉包息息相關(guān),即使本身并不會(huì)真的使用閉包。

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

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