javascript閉包的形成圖解

下面就來說說閉包的一些基本概念和具體的形成過程恶守。

什么是閉包?

閉包就是既能重用一個變量衬吆,又可以保護(hù)變量不被污染的一種機(jī)制 收恢。下面就通過一個小例子來幫助大家理解閉包的作用武学。

var i=1;
function add(){
 console.log(i++);
}
add() //1
add() //2
i=1;
add() // 1
add() // 2

假如上面的程序是用來取號排隊乘地鐵的,由于程序小哥哥的粗心大意伦意,在中間某個地方給全局的變量i重新賦值火窒,導(dǎo)致最后的取號重復(fù)啦,這是會導(dǎo)致非常不友好的后果的默赂,估計廣州的3號線天天得有人干架E嫱摇(這就是上面所說的變量受到污染)。
導(dǎo)致上面變量污染的最基本原因就是i是一個全局變量缆八,那么如果把i變成了函數(shù)內(nèi)部的局部變量,又會出現(xiàn)什么樣的情況呢疾捍?

function add(){
 var i=1;
 console.log(i++);
}
add() //1
add() //1
i=2;
add() // 1
add() // 1

上面這種情況也很好理解奈辰,因為每次調(diào)用完add()后,add自己的函數(shù)作用域AO就會被釋放乱豆,所以每次得到的結(jié)果都為1奖恰,這種情況估計地鐵里面的工作人員都要被****。很明顯,這是因為i為函數(shù)內(nèi)容自己的局部變量瑟啃,既不能重用的原因论泛。所以,閉包就是為了解決上面這種問題的(重用一個變量蛹屿,又可以保護(hù)變量不被污染)屁奏;

閉包的書寫步驟:

1.用外層函數(shù)包裹住受保護(hù)的變量和內(nèi)層函數(shù)
2.外層函數(shù)將內(nèi)層函數(shù)返回到外部
3.使用者調(diào)用外層函數(shù)獲得返回的內(nèi)層函數(shù)對象

function() outer{
  var i=1;
  return function(){
  console.log(i++);
}
}
vat getNum=outer();
getNum();//1
getNum();//2
i=1;
getNum();//3
getNum();//4

由上面例子可以看出,變量i既能重用错负,又不會被污染坟瓢。那到底閉包底層的原理是什么呢?說得概括一點(diǎn)就是犹撒,外層函outer的作用域AO無法釋放折联。可能這句話大家看得很懵逼识颊,下面就通過圖解的方式诚镰,幫助大家簡單明了地理解閉包的底層原理。
1.首先程序在剛開始執(zhí)行之前祥款,會創(chuàng)建ECS執(zhí)行環(huán)境棧,用來存放一些變量或函數(shù)怕享。


image.png

2.程序開始執(zhí)行的時候,首先創(chuàng)建一個outer函數(shù)镰踏,和全局的getNum變量函筋,所以此時window中會存放入outer和getNum


image.png

3.當(dāng)outer函數(shù)被調(diào)用的時候,outer會放到ECS執(zhí)行環(huán)境棧中奠伪,并且創(chuàng)建一個outer的執(zhí)行環(huán)境AO跌帐,當(dāng)執(zhí)行到

var i=1這句代碼的時候,outer的AO中就有了自己的局部變量i绊率,


image.png

4.繼續(xù)往下執(zhí)行到return function() {console.log(i++);} 的時候谨敛,引擎就會創(chuàng)建一個函數(shù),此時這個函數(shù)的祖籍為outer滤否,不再是window脸狸,然后outer會把這個函數(shù)的地址返回給getNum,也就是說藐俺,這時候的getNum引用的就是outer內(nèi)部return出來的小函數(shù)炊甲,而內(nèi)部函數(shù)的祖籍又是outer,outer的parent又是window欲芹,此時就形成了一種相互抱團(tuán)的情況卿啡。


image.png

圖片中綠色的箭頭,就是相互之間作用域鏈關(guān)系菱父。
5.當(dāng)outer調(diào)用完以后颈娜,outer會從ECS中釋放剑逃,正常來說,outer的AO也會被跟著釋放官辽,但是請注意蛹磺,這時候outer的AO 被內(nèi)部的函數(shù)牽引著,因為內(nèi)部函數(shù)的scope指向outer的AO同仆,這就好比你手機(jī)上的微信一樣萤捆,只要你還用得著,就不會把它卸載掉一樣乓梨。也許你會問啦鳖轰,那內(nèi)部的function不會被釋放嗎?因為outer把內(nèi)部的函數(shù)給return出來啦扶镀,所以此時的內(nèi)部函數(shù)又被gerNum牽引著蕴侣,故內(nèi)部函數(shù)也釋放不了,閉包就此形成臭觉。
image.png

6.當(dāng)執(zhí)行g(shù)etNum()的時候昆雀,getNum就會被存放到ECS中,并且創(chuàng)造getNum的AO蝠筑,但是因為getNum沒有自己的局部變量i狞膘,當(dāng)函數(shù)內(nèi)部執(zhí)行到console.log(i++)的時候,他就會沿著作用域鏈什乙,往他的父集outer的AO中去尋找變量i挽封,輸出后并且執(zhí)行i++,outer中的i就變了2


image.png

7.當(dāng)執(zhí)行到 i=1的時候臣镣,因為全局window中沒有變量i辅愿,程序就會自動在全局中聲明一個全局變量i,并且其值為1忆某,此時并不會去操作outer函數(shù)AO中的局部變量i点待,所以outer執(zhí)行環(huán)境中的變量i并不會受到污染。
以上就是對閉包的概念和形成原理的一些解釋弃舒,希望可以幫助到一些需要的碼友們癞埠。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市聋呢,隨后出現(xiàn)的幾起案子苗踪,更是在濱河造成了極大的恐慌,老刑警劉巖坝冕,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件徒探,死亡現(xiàn)場離奇詭異,居然都是意外死亡喂窟,警方通過查閱死者的電腦和手機(jī)测暗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磨澡,“玉大人碗啄,你說我怎么就攤上這事∥壬悖” “怎么了稚字?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長厦酬。 經(jīng)常有香客問我胆描,道長,這世上最難降的妖魔是什么仗阅? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任昌讲,我火速辦了婚禮,結(jié)果婚禮上减噪,老公的妹妹穿的比我還像新娘短绸。我一直安慰自己,他們只是感情好筹裕,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布醋闭。 她就那樣靜靜地躺著,像睡著了一般朝卒。 火紅的嫁衣襯著肌膚如雪证逻。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天抗斤,我揣著相機(jī)與錄音囚企,去河邊找鬼。 笑死豪治,一個胖子當(dāng)著我的面吹牛洞拨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播负拟,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼烦衣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掩浙?” 一聲冷哼從身側(cè)響起花吟,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厨姚,沒想到半個月后衅澈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谬墙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年今布,在試婚紗的時候發(fā)現(xiàn)自己被綠了经备。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡部默,死狀恐怖侵蒙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情傅蹂,我是刑警寧澤纷闺,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站份蝴,受9級特大地震影響犁功,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜婚夫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一浸卦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧请敦,春花似錦镐躲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至匣椰,卻和暖如春裆熙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背禽笑。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工入录, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人佳镜。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓僚稿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蟀伸。 傳聞我的和親對象是個殘疾皇子蚀同,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評論 2 361

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

  • 第一章 錯誤處理: 錯誤: 程序運(yùn)行過程中,導(dǎo)致程序無法正常執(zhí)行的現(xiàn)象(即bug) 現(xiàn)象: 程序一旦出錯啊掏,默認(rèn)會報...
    fastwe閱讀 1,121評論 0 1
  • 原文:http://dmitrysoshnikov.com/ecmascript/javascript-the-c...
    jaysoul閱讀 478評論 0 0
  • 來源于 現(xiàn)代JavaScript教程閉包章節(jié)中文翻譯計劃本文很清晰地解釋了閉包是什么蠢络,以及閉包如何產(chǎn)生,相信你看完...
    71f241c96a34閱讀 584評論 0 1
  • var getAuthor = (function (){ 今天我們來談?wù)勯]包的概念和理解迟蜜。閉包設(shè)計的理念也...
    風(fēng)清揚(yáng)101閱讀 202評論 0 0
  • 函數(shù)作用域 要理解閉包刹孔,必須從理解函數(shù)被調(diào)用時都會發(fā)生什么入手。 我們知道娜睛,每個javascript函數(shù)都是一個對...
    黎貝卡beka閱讀 495評論 0 2