基本概念:
它由兩部分組成胶果。執(zhí)行上下文(代號(hào)A)匾嘱,以及在該執(zhí)行上下文中創(chuàng)建的函數(shù)(代號(hào)B)。
當(dāng)B執(zhí)行時(shí)早抠,如果訪問了A中變量對(duì)象中的值霎烙,那么閉包就會(huì)產(chǎn)生。
紅寶書中的解釋是:
指有權(quán)訪問另一個(gè)函數(shù)作用域中變量的函數(shù),即指的是B悬垃。
但在chrome中的closure指的是A游昼。
但其實(shí)主要的是閉包是有A和B構(gòu)成的,兩者只是在稱呼上有所區(qū)別尝蠕。
原理
在調(diào)用一個(gè)函數(shù)時(shí)烘豌,會(huì)為這個(gè)函數(shù)創(chuàng)建一個(gè)執(zhí)行上下文,并創(chuàng)建一個(gè)作用域鏈看彼。
外部函數(shù)的活動(dòng)對(duì)象是內(nèi)部函數(shù)的作用域鏈上的第二個(gè)活動(dòng)對(duì)象廊佩,向外延伸,直至全局執(zhí)行上下文闲昭。
函數(shù)執(zhí)行完畢后罐寨,局部活動(dòng)對(duì)象會(huì)被銷毀。
但閉包不同序矩,內(nèi)部函數(shù)會(huì)把其包含的外部活動(dòng)對(duì)象添加到自己的作用域鏈中鸯绿,所以當(dāng)外部函數(shù)執(zhí)行完成后,其執(zhí)行上下文的作用域會(huì)被銷毀簸淀,但被內(nèi)部函數(shù)引用的活動(dòng)對(duì)象然后會(huì)被保留瓶蝴。
除非內(nèi)部函數(shù)被銷毀了,其引用的活動(dòng)對(duì)象才會(huì)被銷毀租幕。
這也就形成了閉包舷手。
場(chǎng)景
閉包的場(chǎng)景隨處可見,ajax的回調(diào)劲绪,事件的回調(diào)男窟,定時(shí)器,或者一個(gè)函數(shù)內(nèi)部返回一個(gè)另一個(gè)匿名函數(shù)等等
作用
通過閉包贾富,在其他的執(zhí)行上下文中歉眷,訪問到函數(shù)的內(nèi)部變量。
優(yōu)點(diǎn):
- 形成私有變量颤枪,形成封裝
- 模塊化開發(fā)汗捡,防止全局污染。
- 用于緩存畏纲,因?yàn)楸3至藢?duì)變量的持久引用
缺點(diǎn):
但過度使用閉包會(huì)有內(nèi)存溢出的風(fēng)險(xiǎn),這是因?yàn)锽作用域內(nèi)的引用了A作用域中的變量扇住,導(dǎo)致A執(zhí)行完后,不能清除作用域盗胀,保持了對(duì)內(nèi)存的占用艘蹋。所以過度使用,是存在風(fēng)險(xiǎn)的票灰。
參考
《JavaScript高級(jí)程序設(shè)計(jì)》
前端基礎(chǔ)進(jìn)階(五):閉包
JavaScript中閉包的概念簿训、原理咱娶、作用及應(yīng)用
當(dāng)面試官問你閉包時(shí),他究竟想聽到些什么强品?
Javascript 閉包并非魔法