[ JS 進(jìn)階 ] 閉包盆犁,作用域鏈命咐,垃圾回收,內(nèi)存泄露

來(lái)看一些關(guān)于閉包的定義:

1.閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中變量的函數(shù) --《JS高級(jí)程序設(shè)計(jì)第三版》 p178

2.函數(shù)對(duì)象可以通過(guò)作用域鏈相關(guān)聯(lián)起來(lái)蚣抗,函數(shù)體內(nèi)部的變量都可以保存在函數(shù)作用域內(nèi)侈百,這種特性稱(chēng)為 ‘閉包’ 悯周。 --《JS權(quán)威指南》 p183

3.內(nèi)部函數(shù)可以訪問(wèn)定義它們的外部函數(shù)的參數(shù)和變量(除了this和arguments)前塔。 --《JS語(yǔ)言精粹》p36

來(lái)個(gè)定義總結(jié)

1.可以訪問(wèn)外部函數(shù)作用域中變量的函數(shù)

2.被內(nèi)部函數(shù)訪問(wèn)的外部函數(shù)的變量可以保存在外部函數(shù)作用域內(nèi)而不被回收---這是核心,后面我們遇到閉包都要想到妇萄,我們要重點(diǎn)關(guān)注被閉包引用的這個(gè)變量锭魔。

創(chuàng)建一個(gè)閉包:

var sayName =function(){

????var name ='jozo';

????return function(){?

?????????alert(name);

?????}

};

var say = sayName();

?say();

var say = sayName()?:返回了一個(gè)匿名的內(nèi)部函數(shù)保存在變量say中例证,并且引用了外部函數(shù)的變量name,由于垃圾回收機(jī)制迷捧,sayName函數(shù)執(zhí)行完畢后织咧,變量name并沒(méi)有被銷(xiāo)毀。

say()?:執(zhí)行返回的內(nèi)部函數(shù)漠秋,依然能訪問(wèn)變量name,輸出 'jozo' .

2. 閉包中的作用域鏈

變量在作用域中的查找方式應(yīng)該都很熟悉了笙蒙,其實(shí)這就是順著作用域鏈往上查找的。

當(dāng)函數(shù)被調(diào)用時(shí):

1.先創(chuàng)建一個(gè)執(zhí)行環(huán)境(execution context),及相應(yīng)的作用域鏈庆锦;

2.將arguments和其他命名參數(shù)的值添加到函數(shù)的活動(dòng)對(duì)象(activation object)

作用域鏈:當(dāng)前函數(shù)的活動(dòng)對(duì)象優(yōu)先級(jí)最高捅位,外部函數(shù)的活動(dòng)對(duì)象次之,外部函數(shù)的外部函數(shù)的活動(dòng)對(duì)象依次遞減搂抒,直至作用域鏈的末端--全局作用域艇搀。優(yōu)先級(jí)就是變量查找的先后順序;

3. 閉包的實(shí)例

實(shí)例1:實(shí)現(xiàn)累加

// 方式1

var a =0;

var add=function(){

? ? a++;

? ? console.log(a)

}

add();

add();

//方式2 :閉包

var add= (function(){

? ? var? a = 0;

? ? return function(){

? ? ? ? a++;

? ? ? ? console.log(a);

? ? }})();

console.log(a);//undefined

add();

add();

實(shí)例2 :給每個(gè)li添加點(diǎn)擊事件

var oli =document.getElementsByTagName('li');

var i;

for(i =0;i <5;i++){?

? ???oli[i].onclick =function(){?

?? ??????alert(i);?

?? ??}?

}

console.log(i);// 5

//執(zhí)行匿名函數(shù)

(function(){?

?alert(i);? ?//5

}());?

上面是一個(gè)經(jīng)典的例子求晶,我們都知道執(zhí)行結(jié)果是都彈出5焰雕,也知道可以用閉包解決這個(gè)問(wèn)題,但是我剛開(kāi)始始終不能明白為什么每次彈出都是5芳杏,為什么閉包可以解決這問(wèn)題矩屁。后來(lái)捋一捋還是把它弄清晰了:

a.?先來(lái)分析沒(méi)用閉包前的情況:for循環(huán)中,我們給每個(gè)li點(diǎn)擊事件綁定了一個(gè)匿名函數(shù)辟宗,匿名函數(shù)中返回了變量i的值,當(dāng)循環(huán)結(jié)束后档插,變量i的值變?yōu)?慢蜓,此時(shí)我們?cè)偃c(diǎn)擊每個(gè)li,也就是執(zhí)行相應(yīng)的匿名函數(shù)(看上面的代碼)郭膛,這是變量i已經(jīng)是5了晨抡,所以每個(gè)點(diǎn)擊彈出5. 因?yàn)檫@里返回的每個(gè)匿名函數(shù)都是引用了同一個(gè)變量i,如果我們新建一個(gè)變量保存循環(huán)執(zhí)行時(shí)當(dāng)前的i的值则剃,然后再讓匿名函數(shù)應(yīng)用這個(gè)變量耘柱,最后再返回這個(gè)匿名函數(shù),這樣就可以達(dá)到我們的目的了棍现,這就是運(yùn)用閉包來(lái)實(shí)現(xiàn)的调煎!

4. 閉包的運(yùn)用

01.匿名自執(zhí)行函數(shù)

02.實(shí)現(xiàn)封裝/模塊化代碼

var person=function(){

? ??//變量作用域?yàn)楹瘮?shù)內(nèi)部,外部無(wú)法訪問(wèn)?

?? ??var name ="default";

? ??return{

? ??????????getName:function(){

? ??????????????????return name;?

? ??????????},

? ??????setName:function(newName){?

?? ??????????name = newName;?

? ???????}

? ???}?

?}();

console.log(person.name);//直接訪問(wèn)己肮,結(jié)果為undefined?

console.log(person.getName());//default?

person.setName("jozo");

console.log(person.getName());//jozo

03. 實(shí)現(xiàn)面向?qū)ο笾械膶?duì)象

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末士袄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子谎僻,更是在濱河造成了極大的恐慌娄柳,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件艘绍,死亡現(xiàn)場(chǎng)離奇詭異赤拒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)诱鞠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)挎挖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人航夺,你說(shuō)我怎么就攤上這事蕉朵。” “怎么了阳掐?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵墓造,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锚烦,道長(zhǎng),這世上最難降的妖魔是什么帝雇? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任涮俄,我火速辦了婚禮,結(jié)果婚禮上尸闸,老公的妹妹穿的比我還像新娘彻亲。我一直安慰自己孕锄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布苞尝。 她就那樣靜靜地躺著畸肆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪宙址。 梳的紋絲不亂的頭發(fā)上轴脐,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音抡砂,去河邊找鬼大咱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛注益,可吹牛的內(nèi)容都是我干的碴巾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼丑搔,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼厦瓢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起啤月,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤煮仇,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后顽冶,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體欺抗,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年强重,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绞呈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡间景,死狀恐怖佃声,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倘要,我是刑警寧澤圾亏,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站封拧,受9級(jí)特大地震影響志鹃,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜泽西,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一曹铃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧捧杉,春花似錦陕见、人聲如沸秘血。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)灰粮。三九已至,卻和暖如春忍坷,著一層夾襖步出監(jiān)牢的瞬間粘舟,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工承匣, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蓖乘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓韧骗,卻偏偏與公主長(zhǎng)得像嘉抒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子袍暴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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