閉包

前情提要:

?JS變量分為兩種:局部變量全局變量

*函數(shù)內(nèi)部可以直接訪問全局變量铐伴。

函數(shù)內(nèi)部直接訪問全局變量

*而函數(shù)外部卻無法訪問函數(shù)內(nèi)部的變量宿稀。

函數(shù)外部無法訪問局部變量

引申出一個(gè)問題:如何在函數(shù)外部訪問函數(shù)內(nèi)部的變量呢续搀?

函數(shù)外部訪問局部變量

? ?既然inner可以讀取outer中的局部變量,那么只要把inner作為返回值止喷,我們就可以在outer外部讀取它的內(nèi)部變量了嗎 擦囊。

? ? 于是“閉包”概念誕生违霞。

什么是閉包?

? ? ?閉包就是:能夠讀取其他函數(shù)內(nèi)部變量的【函數(shù)】瞬场,在javascript中葛家,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,所以閉包可以理解成“定義在一個(gè)函數(shù)內(nèi)部的【函數(shù)】“泌类。在本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部連接起來的橋梁。

? ? ?進(jìn)一步說:一個(gè)函數(shù)和對其周圍狀態(tài)(lexical environment刃榨,詞法環(huán)境)的引用捆綁在一起(或者說函數(shù)被引用包圍)弹砚,這樣的組合就是閉包closure)。也就是說枢希,閉包讓你可以在一個(gè)內(nèi)層函數(shù)中訪問到其外層函數(shù)的作用域桌吃。在 JavaScript 中,每當(dāng)創(chuàng)建一個(gè)函數(shù)苞轿,閉包就會(huì)在函數(shù)創(chuàng)建的同時(shí)被創(chuàng)建出來茅诱。

閉包特點(diǎn):1:引用外部函數(shù)變量對象中的值;2:在外部函數(shù)的外部被調(diào)用

簡單的閉包實(shí)現(xiàn)
外部函數(shù)訪問局部變量


閉包的作用

? ? 閉包可以用來【間接的訪問一個(gè)變量】搬卒,相當(dāng)于把【變量隱藏】瑟俭,如果寫全局變量就可能會(huì)被人隨意修改,所以我們可以定義一個(gè)不能讓人【直接訪問】到的局部變量契邀,然后再寫一個(gè)【函數(shù)】作為訪問器把變量暴露出去摆寄。

從堆棧的角度看閉包

? ? ??在程序運(yùn)行時(shí),計(jì)算機(jī)會(huì)為應(yīng)用程序分配一定的內(nèi)存空間坯门;應(yīng)用程序則會(huì)自行分配所獲得的內(nèi)存空間微饥,其中一部分被用于記錄程序中正在調(diào)用的各個(gè)函數(shù)的運(yùn)行情況,這就是函數(shù)的調(diào)用棧古戴。常規(guī)的函數(shù)調(diào)用總是會(huì)在調(diào)用棧最上層添加一個(gè)新的堆棧幀(stack frame欠橘,也翻譯為“棧幀”或簡稱為“幀”),這個(gè)過程被稱作“入椣帜眨”或“壓椝嘈”(意即把新的幀壓在棧頂)。

? ?回顧基礎(chǔ):基本變量的值一般都是存在棧內(nèi)存中述暂,而對象類型的變量的值存儲(chǔ)在堆內(nèi)存中痹升,棧內(nèi)存存儲(chǔ)對應(yīng)空間地址。

創(chuàng)建棧流程

? ? ? 首先在全局執(zhí)行環(huán)境中畦韭,我們可以訪問到變量a和fn疼蛾,進(jìn)入fn時(shí)棧內(nèi)存會(huì)push一個(gè)fn的執(zhí)行環(huán)境,這個(gè)環(huán)境里有變量b和函數(shù)fn1艺配,也可以訪問到全局的執(zhí)行環(huán)境察郁。進(jìn)入fn1時(shí),棧內(nèi)存會(huì)push一個(gè)fn1的執(zhí)行環(huán)境转唉,這個(gè)執(zhí)行環(huán)境下無變量皮钠,但是可以訪問到fn執(zhí)行環(huán)境和全局環(huán)境下的變量。

? ? ?隨著fn1()執(zhí)行完畢赠法,fn1的執(zhí)行環(huán)境被杯銷毀麦轰,接著執(zhí)行完fn(),fn的執(zhí)行環(huán)境也會(huì)被銷毀,只剩全局的執(zhí)行環(huán)境下款侵,現(xiàn)在沒有b變量末荐,和fn1函數(shù)對象了,只有a 和 fn(函數(shù)聲明作用域是window下)新锈。

? ? 在函數(shù)內(nèi)訪問某個(gè)變量是根據(jù)函數(shù)作用域鏈來判斷變量是否存在的甲脏,而函數(shù)作用域鏈?zhǔn)浅绦蚋鶕?jù)函數(shù)所在的執(zhí)行環(huán)境棧來初始化的,因?yàn)槌绦蛟谠L問變量時(shí)妹笆,是【向底層棧一個(gè)個(gè)找】的块请。

閉包實(shí)際情況:

當(dāng)執(zhí)行完result = outer這一句之后,outer函數(shù)并沒有被銷毀拳缠,因?yàn)樗锩娴淖兞咳员籭nner的函數(shù)作用域鏈所引用墩新,當(dāng)執(zhí)行完inner之后,inner和outer的執(zhí)行環(huán)境才會(huì)被銷毀脊凰。

閉包的優(yōu)缺點(diǎn)

它的最大用處有兩個(gè):

? ? ? ? ?1抖棘、可以讀取函數(shù)內(nèi)部的變量

? ? ? ? ?2、就是讓這些變量的值始終保持在內(nèi)存中狸涌。

閉包的缺點(diǎn)就是常駐內(nèi)存會(huì)【增大內(nèi)存使用量】切省,并且使用不當(dāng)很容易造成內(nèi)存泄露∨恋ǎ《JavaScript高級編程》書中建議:由于閉包會(huì)攜帶包含它的函數(shù)的作用域朝捆,因?yàn)闀?huì)比其他函數(shù)占用更多內(nèi)容,過度使用閉包懒豹,會(huì)導(dǎo)致內(nèi)存占用過多芙盘。

如果不是因?yàn)槟承┨厥馊蝿?wù)而需要閉包,在沒有必要的情況下脸秽,在其它函數(shù)中創(chuàng)建函數(shù)是不明智的儒老,因?yàn)殚]包對腳本性能具有負(fù)面影響,包括處理速度和內(nèi)存消耗记餐。

閉包的使用場景

1:setTimeout/setInterval

2:回調(diào)函數(shù)(callback)

3:事件句柄(event handle)



參考博客:

1:https://zhuanlan.zhihu.com/p/22486908

2:https://www.cnblogs.com/sandaizi/p/11582488.html

3:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驮樊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子片酝,更是在濱河造成了極大的恐慌囚衔,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雕沿,死亡現(xiàn)場離奇詭異练湿,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)审轮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門肥哎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來辽俗,“玉大人,你說我怎么就攤上這事贤姆∮馨” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵霞捡,是天一觀的道長。 經(jīng)常有香客問我薄疚,道長碧信,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任街夭,我火速辦了婚禮砰碴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘板丽。我一直安慰自己呈枉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布埃碱。 她就那樣靜靜地躺著猖辫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪砚殿。 梳的紋絲不亂的頭發(fā)上啃憎,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音似炎,去河邊找鬼辛萍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛羡藐,可吹牛的內(nèi)容都是我干的贩毕。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼仆嗦,長吁一口氣:“原來是場噩夢啊……” “哼辉阶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起欧啤,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤睛藻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后邢隧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體店印,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年倒慧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了按摘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片包券。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖炫贤,靈堂內(nèi)的尸體忽然破棺而出溅固,到底是詐尸還是另有隱情,我是刑警寧澤兰珍,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布侍郭,位于F島的核電站,受9級特大地震影響掠河,放射性物質(zhì)發(fā)生泄漏亮元。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一唠摹、第九天 我趴在偏房一處隱蔽的房頂上張望爆捞。 院中可真熱鬧,春花似錦勾拉、人聲如沸煮甥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽成肘。三九已至,卻和暖如春找默,著一層夾襖步出監(jiān)牢的瞬間艇劫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工惩激, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留店煞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓风钻,卻偏偏與公主長得像顷蟀,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子骡技,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1、什么是閉包是趴? 閉包是指有權(quán)訪問另外一個(gè)函數(shù)作用域中的變量的函數(shù)涛舍。可以理解為(能夠讀取另一個(gè)函數(shù)作用域的變量的函...
    為光pig閱讀 800評論 0 0
  • 閉包是js開發(fā)慣用的技巧唆途,什么是閉包富雅? 閉包就是 能夠訪問另一個(gè)函數(shù)作用域的變量的函數(shù) function f1...
    Nicholas_liang閱讀 397評論 0 2
  • 閉包是js開發(fā)慣用的技巧掸驱,什么是閉包?閉包指的是:能夠訪問另一個(gè)函數(shù)作用域的變量的函數(shù)没佑。清晰的講:閉包就是一個(gè)函數(shù)...
    下一站深圳閱讀 115,961評論 35 91
  • 前言 面試問題: 說一下對變量提升的理解 說明this的幾種不同的使用場景 創(chuàng)建10個(gè) 標(biāo)簽毕贼,點(diǎn)擊的時(shí)候彈出來對應(yīng)...
    陳觀齊閱讀 240評論 0 1
  • 1.什么是閉包? 要了解什么是閉包蛤奢,首先你要了解作用域鬼癣。 js的作用域分兩種,全局作用域和局部作用域啤贩。 我們知道在...
    zhudying閱讀 422評論 0 1