js中的閉包

閉包是js的一個難點也是它的一個特色副硅,是我們必須掌握的js高級特性,那么什么是閉包呢翅萤?它又有什么用呢恐疲?

我們都知道,js的作用域分兩種套么,全局局部培己,基于我們所熟悉的作用域鏈相關(guān)知識,我們知道在js作用域環(huán)境中訪問變量的權(quán)利是由內(nèi)向外的胚泌,內(nèi)部作用域可以獲得當(dāng)前作用域下的變量并且可以獲得當(dāng)前包含當(dāng)前作用域的外層作用域下的變量省咨,反之則不能,也就是說在外層作用域下無法獲取內(nèi)層作用域下的變量玷室,同樣在不同的函數(shù)作用域中也是不能相互訪問彼此變量的零蓉,那么我們想在一個函數(shù)內(nèi)部也有限權(quán)訪問另一個函數(shù)內(nèi)部的變量該怎么辦呢?閉包就是用來解決這一需求的穷缤,閉包的本質(zhì)就是在一個函數(shù)內(nèi)部創(chuàng)建另一個函數(shù)敌蜂。
我們首先知道閉包有3個特性:
①函數(shù)嵌套函數(shù)
②函數(shù)內(nèi)部可以引用函數(shù)外部的參數(shù)和變量
③參數(shù)和變量不會被垃圾回收機制回收

本文我們以閉包兩種的主要形式來學(xué)習(xí)

在這段代碼中,a()中的返回值是一個匿名函數(shù)津肛,這個函數(shù)在a()作用域內(nèi)部章喉,所以它可以獲取a()作用域下變量name的值,將這個值作為返回值賦給全局作用域下的變量b,實現(xiàn)了在全局變量下獲取到局部變量中的變量的值

再來看一個閉包的經(jīng)典例子

在這里插入圖片描述

一般情況下,在函數(shù)fn執(zhí)行完后秸脱,就應(yīng)該連同它里面的變量一同被銷毀落包,但是在這個例子中,匿名函數(shù)作為fn的返回值被賦值給了fn1摊唇,這時候相當(dāng)于fn1=function(){var n = 0 … }妥色,并且匿名函數(shù)內(nèi)部引用著fn里的變量num,所以變量num無法被銷毀遏片,而變量n是每次被調(diào)用時新創(chuàng)建的嘹害,所以每次fn1執(zhí)行完后它就把屬于自己的變量連同自己一起銷毀,于是乎最后就剩下孤零零的num吮便,于是這里就產(chǎn)生了內(nèi)存消耗的問題

再來看一個經(jīng)典例子-定時器與閉包

寫一個for循環(huán)笔呀,讓它按順序打印出當(dāng)前循環(huán)次數(shù)


按照預(yù)期它應(yīng)該依次輸出1 2 3 4 5,而結(jié)果它輸出了五次5髓需,這是為什么呢许师?原來由于js是單線程的,所以在執(zhí)行for循環(huán)的時候定時器setTimeout被安排到任務(wù)隊列中排隊等待執(zhí)行僚匆,而在等待過程中for循環(huán)就已經(jīng)在執(zhí)行微渠,等到setTimeout可以執(zhí)行的時候,for循環(huán)已經(jīng)結(jié)束咧擂,i的值也已經(jīng)編程5逞盆,所以打印出來五個5,那么我們?yōu)榱藢崿F(xiàn)預(yù)期結(jié)果應(yīng)該怎么改這段代碼呢松申?(ps:如果把for循環(huán)里面的var變成let云芦,也能實現(xiàn)預(yù)期結(jié)果)

引入閉包來保存變量i,將setTimeout放入立即執(zhí)行函數(shù)中贸桶,將for循環(huán)中的循環(huán)值i作為參數(shù)傳遞舅逸,100毫秒后同時打印出1 2 3 4 5

那如果我們想實現(xiàn)每隔100毫秒分別依次輸出數(shù)字,又該怎么改呢?

在這段代碼中皇筛,相當(dāng)于同時啟動3個定時器琉历,i*100是為4個定時器分別設(shè)置了不同的時間,同時啟動水醋,但是執(zhí)行時間不同旗笔,每個定時器間隔都是100毫秒,實現(xiàn)了每隔100毫秒就執(zhí)行一次打印的效果离例。

②閉包作為參數(shù)傳遞

在這段代碼中换团,函數(shù)fn1作為參數(shù)傳入立即執(zhí)行函數(shù)中,在執(zhí)行到fn2(30)的時候宫蛆,30作為參數(shù)傳入fn1中艘包,這時候if(x>num)中的num取的并不是立即執(zhí)行函數(shù)中的num的猛,而是取創(chuàng)建函數(shù)的作用域中的num這里函數(shù)創(chuàng)建的作用域是全局作用域下,所以num取的是全局作用域中的值15想虎,即30>15卦尊,打印30

最后總結(jié)一下閉包的好處與壞處

好處

①保護函數(shù)內(nèi)的變量安全 ,實現(xiàn)封裝舌厨,防止變量流入其他環(huán)境發(fā)生命名沖突

②在內(nèi)存中維持一個變量岂却,可以做緩存(但使用多了同時也是一項缺點,消耗內(nèi)存)

③匿名自執(zhí)行函數(shù)可以減少內(nèi)存消耗

壞處

①其中一點上面已經(jīng)有體現(xiàn)了裙椭,就是被引用的私有變量不能被銷毀躏哩,增大了內(nèi)存消耗,造成內(nèi)存泄漏揉燃,解決方法是可以在使用完變量后手動為它賦值為null扫尺;

②其次由于閉包涉及跨域訪問,所以會導(dǎo)致性能損失炊汤,我們可以通過把跨作用域變量存儲在局部變量中正驻,然后直接訪問局部變量,來減輕對執(zhí)行速度的影響

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抢腐,一起剝皮案震驚了整個濱河市姑曙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迈倍,老刑警劉巖伤靠,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異授瘦,居然都是意外死亡醋界,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門提完,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丘侠,你說我怎么就攤上這事徒欣。” “怎么了蜗字?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵打肝,是天一觀的道長。 經(jīng)常有香客問我挪捕,道長粗梭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任级零,我火速辦了婚禮断医,結(jié)果婚禮上滞乙,老公的妹妹穿的比我還像新娘。我一直安慰自己鉴嗤,他們只是感情好斩启,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著醉锅,像睡著了一般兔簇。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上硬耍,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天垄琐,我揣著相機與錄音,去河邊找鬼经柴。 笑死此虑,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的口锭。 我是一名探鬼主播朦前,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼鹃操!你這毒婦竟也來了韭寸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤荆隘,失蹤者是張志新(化名)和其女友劉穎恩伺,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體椰拒,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡晶渠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了燃观。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片褒脯。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖缆毁,靈堂內(nèi)的尸體忽然破棺而出番川,到底是詐尸還是另有隱情,我是刑警寧澤脊框,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布颁督,位于F島的核電站,受9級特大地震影響浇雹,放射性物質(zhì)發(fā)生泄漏沉御。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一昭灵、第九天 我趴在偏房一處隱蔽的房頂上張望吠裆。 院中可真熱鬧伐谈,春花似錦、人聲如沸硫痰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽效斑。三九已至非春,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缓屠,已是汗流浹背奇昙。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留敌完,地道東北人储耐。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像滨溉,于是被迫代替她去往敵國和親什湘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

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

  • 一晦攒、情景引入: 關(guān)于js的作用域闽撤,我們都知道: 1.js的作用域分兩種,全局和局部 2.在js作用域環(huán)境中訪問變量...
    追尋1989閱讀 202評論 0 1
  • 在上一篇文章“執(zhí)行環(huán)境和作用域”中脯颜,我試著梳理了執(zhí)行環(huán)境和作用域的關(guān)系哟旗。但實際上,文章中并沒有提到作用域栋操,而是介紹...
    海痕閱讀 239評論 0 0
  • 首先,js閉包對于哪怕是有很多年前端開發(fā)經(jīng)驗的人,也是很晦澀難懂的東西. 所以,我不敢保證能把你說明白,但是如果你...
    火鍋伯南克閱讀 410評論 0 1
  • 閉包是js中一個晦澀難懂的一個概念闸餐,網(wǎng)上關(guān)于閉包的文章也是抓一大把,每個人的文章卻又不盡相同矾芙,或者說舍沙,每個人的理解...
    coolcao閱讀 160評論 0 2
  • 在js中的學(xué)習(xí)中,總會遇到一個陌生又晦澀蠕啄,然后還是陌生的詞匯场勤,那就是閉包。 首先歼跟,什么是閉包? 其次格遭,閉包的作用是...
    林llgb閱讀 1,567評論 0 1