如何查看一個(gè)網(wǎng)站是用什么程序做的南寧企業(yè)官網(wǎng)seo
了解閉包的前提必須得了解什么是作用域鏈。也就是(一)的內(nèi)容。
參考:
瀏覽器工作原理與實(shí)踐
破解前端面試:從閉包說起
閉包
閉包是一個(gè)可以訪問外部作用域中變量的內(nèi)部函數(shù),因?yàn)閮?nèi)部函數(shù)引用了外部函數(shù)的變量,導(dǎo)致這些變量無法被回收,將持久保存在作用域內(nèi),這就形成了一個(gè)閉包。
這些被引用的變量直到閉包被銷毀時(shí)才會(huì)被銷毀。
在 JavaScript 中,根據(jù)詞法作用域的規(guī)則,內(nèi)部函數(shù)總是可以訪問其外部函數(shù)中聲明的變量,當(dāng)通過調(diào)用一個(gè)外部函數(shù)返回一個(gè)內(nèi)部函數(shù)后,即使該外部函數(shù)已經(jīng)執(zhí)行結(jié)束了,但是內(nèi)部函數(shù)引用外部函數(shù)的變量依然保存在內(nèi)存中,我們就把這些變量的集合稱為閉包。比如外部函數(shù)是 foo,那么這些變量的集合就稱為 foo 函數(shù)的閉包。
閉包必須要引用到外部函數(shù)的變量,如果沒有引用到的話,外部函數(shù)執(zhí)行完之后,JS引擎執(zhí)行垃圾回收時(shí)會(huì)認(rèn)為這個(gè)外部函數(shù)已經(jīng)執(zhí)行完了,執(zhí)行環(huán)境中沒有變量被正在引用或者使用,所以可以銷毀。
閉包的回收
如果閉包是一個(gè)全局變量,頁面關(guān)閉時(shí)它才會(huì)被回收,如果是局部變量,則引用它的函數(shù)執(zhí)行完畢后,JS引擎垃圾回收時(shí)會(huì)將它銷毀。
如果這個(gè)全局變量的閉包占用了許多內(nèi)存,又以后不再使用的話,就會(huì)造成內(nèi)存泄漏(該內(nèi)存空間使用完畢之后未被回收)。
因此如果該閉包會(huì)一直使用,那么它可以作為全局變量而存在;但如果使用頻率不高,而且占用內(nèi)存又比較大的話,那就盡量讓它成為一個(gè)局部變量。
使用
其實(shí)我們經(jīng)常使用到了閉包卻沒有發(fā)現(xiàn)。
-
防抖節(jié)流,setTimeout
(function autorun(){let x = 1;setTimeout(function log(){console.log(x);}, 10000); })();
變量 x 將一直存活著直到定時(shí)器的回調(diào)執(zhí)行或者 clearTimeout() 被調(diào)用。 如果這里使用的是 setInterval() ,那么變量 x 將一直存活到 clearInterval() 被調(diào)用。
-
DOM節(jié)點(diǎn)事件
(function autorun(){let x = 1;$("#btn").on("click", function log(){console.log(x);}); })();
當(dāng)變量 x 在事件處理函數(shù)中被使用時(shí),它將一直存活直到該事件處理函數(shù)被移除。
-
異步事件 Promise
(function autorun(){let x = 1;fetch("http://").then(function log(){console.log(x);}); })();
變量 x 將一直存活到接收到后端返回結(jié)果,回調(diào)函數(shù)被執(zhí)行。